[Lldb-commits] [lldb] [lldb] Return *const* UnwindPlan pointers from FuncUnwinders (PR #133247)
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Thu Mar 27 06:38:50 PDT 2025
https://github.com/labath updated https://github.com/llvm/llvm-project/pull/133247
>From f4f4d06e485b5d7d28ef2a45ae53d630df5da1c1 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Thu, 27 Mar 2025 13:53:57 +0100
Subject: [PATCH 1/2] [lldb] Return *const* UnwindPlan pointers from
FuncUnwinders
These plans are cached and accessed from multiple threads. Modifying
them would be a Bad Idea(tm).
---
lldb/include/lldb/Symbol/FuncUnwinders.h | 78 +++----
lldb/include/lldb/Symbol/UnwindPlan.h | 4 +-
.../lldb/Target/RegisterContextUnwind.h | 16 +-
lldb/source/Commands/CommandObjectTarget.cpp | 106 +++++----
lldb/source/Symbol/FuncUnwinders.cpp | 207 +++++++++---------
lldb/source/Symbol/UnwindPlan.cpp | 2 +-
lldb/source/Target/RegisterContextUnwind.cpp | 84 ++++---
7 files changed, 247 insertions(+), 250 deletions(-)
diff --git a/lldb/include/lldb/Symbol/FuncUnwinders.h b/lldb/include/lldb/Symbol/FuncUnwinders.h
index 1d4c28324e90f..479ccf87b6e2c 100644
--- a/lldb/include/lldb/Symbol/FuncUnwinders.h
+++ b/lldb/include/lldb/Symbol/FuncUnwinders.h
@@ -36,18 +36,19 @@ class FuncUnwinders {
~FuncUnwinders();
- lldb::UnwindPlanSP GetUnwindPlanAtCallSite(Target &target, Thread &thread);
+ std::shared_ptr<const UnwindPlan> GetUnwindPlanAtCallSite(Target &target,
+ Thread &thread);
- lldb::UnwindPlanSP GetUnwindPlanAtNonCallSite(Target &target,
- lldb_private::Thread &thread);
+ std::shared_ptr<const UnwindPlan>
+ GetUnwindPlanAtNonCallSite(Target &target, lldb_private::Thread &thread);
- lldb::UnwindPlanSP GetUnwindPlanFastUnwind(Target &target,
- lldb_private::Thread &thread);
+ std::shared_ptr<const UnwindPlan>
+ GetUnwindPlanFastUnwind(Target &target, lldb_private::Thread &thread);
- lldb::UnwindPlanSP
+ std::shared_ptr<const UnwindPlan>
GetUnwindPlanArchitectureDefault(lldb_private::Thread &thread);
- lldb::UnwindPlanSP
+ std::shared_ptr<const UnwindPlan>
GetUnwindPlanArchitectureDefaultAtFunctionEntry(lldb_private::Thread &thread);
Address &GetFirstNonPrologueInsn(Target &target);
@@ -77,32 +78,34 @@ class FuncUnwinders {
// used. Instead, clients should ask for the *behavior* they are looking for,
// using one of the above UnwindPlan retrieval methods.
- lldb::UnwindPlanSP GetAssemblyUnwindPlan(Target &target, Thread &thread);
+ std::shared_ptr<const UnwindPlan> GetAssemblyUnwindPlan(Target &target,
+ Thread &thread);
- lldb::UnwindPlanSP GetObjectFileUnwindPlan(Target &target);
+ std::shared_ptr<const UnwindPlan> GetObjectFileUnwindPlan(Target &target);
- lldb::UnwindPlanSP GetObjectFileAugmentedUnwindPlan(Target &target,
- Thread &thread);
+ std::shared_ptr<const UnwindPlan>
+ GetObjectFileAugmentedUnwindPlan(Target &target, Thread &thread);
- lldb::UnwindPlanSP GetEHFrameUnwindPlan(Target &target);
+ std::shared_ptr<const UnwindPlan> GetEHFrameUnwindPlan(Target &target);
- lldb::UnwindPlanSP GetEHFrameAugmentedUnwindPlan(Target &target,
- Thread &thread);
+ std::shared_ptr<const UnwindPlan>
+ GetEHFrameAugmentedUnwindPlan(Target &target, Thread &thread);
- lldb::UnwindPlanSP GetDebugFrameUnwindPlan(Target &target);
+ std::shared_ptr<const UnwindPlan> GetDebugFrameUnwindPlan(Target &target);
- lldb::UnwindPlanSP GetDebugFrameAugmentedUnwindPlan(Target &target,
- Thread &thread);
+ std::shared_ptr<const UnwindPlan>
+ GetDebugFrameAugmentedUnwindPlan(Target &target, Thread &thread);
- lldb::UnwindPlanSP GetCompactUnwindUnwindPlan(Target &target);
+ std::shared_ptr<const UnwindPlan> GetCompactUnwindUnwindPlan(Target &target);
- lldb::UnwindPlanSP GetArmUnwindUnwindPlan(Target &target);
+ std::shared_ptr<const UnwindPlan> GetArmUnwindUnwindPlan(Target &target);
- lldb::UnwindPlanSP GetSymbolFileUnwindPlan(Thread &thread);
+ std::shared_ptr<const UnwindPlan> GetSymbolFileUnwindPlan(Thread &thread);
- lldb::UnwindPlanSP GetArchDefaultUnwindPlan(Thread &thread);
+ std::shared_ptr<const UnwindPlan> GetArchDefaultUnwindPlan(Thread &thread);
- lldb::UnwindPlanSP GetArchDefaultAtFuncEntryUnwindPlan(Thread &thread);
+ std::shared_ptr<const UnwindPlan>
+ GetArchDefaultAtFuncEntryUnwindPlan(Thread &thread);
private:
lldb::UnwindAssemblySP GetUnwindAssemblyProfiler(Target &target);
@@ -113,7 +116,8 @@ class FuncUnwinders {
// unwind rule for the pc, and LazyBoolCalculate if it was unable to
// determine this for some reason.
lldb_private::LazyBool CompareUnwindPlansForIdenticalInitialPCLocation(
- Thread &thread, const lldb::UnwindPlanSP &a, const lldb::UnwindPlanSP &b);
+ Thread &thread, const std::shared_ptr<const UnwindPlan> &a,
+ const std::shared_ptr<const UnwindPlan> &b);
UnwindTable &m_unwind_table;
@@ -129,22 +133,22 @@ class FuncUnwinders {
std::recursive_mutex m_mutex;
- lldb::UnwindPlanSP m_unwind_plan_assembly_sp;
- lldb::UnwindPlanSP m_unwind_plan_object_file_sp;
- lldb::UnwindPlanSP m_unwind_plan_eh_frame_sp;
- lldb::UnwindPlanSP m_unwind_plan_debug_frame_sp;
+ std::shared_ptr<const UnwindPlan> m_unwind_plan_assembly_sp;
+ std::shared_ptr<const UnwindPlan> m_unwind_plan_object_file_sp;
+ std::shared_ptr<const UnwindPlan> m_unwind_plan_eh_frame_sp;
+ std::shared_ptr<const UnwindPlan> m_unwind_plan_debug_frame_sp;
// augmented by assembly inspection so it's valid everywhere
- lldb::UnwindPlanSP m_unwind_plan_object_file_augmented_sp;
- lldb::UnwindPlanSP m_unwind_plan_eh_frame_augmented_sp;
- lldb::UnwindPlanSP m_unwind_plan_debug_frame_augmented_sp;
-
- std::vector<lldb::UnwindPlanSP> m_unwind_plan_compact_unwind;
- lldb::UnwindPlanSP m_unwind_plan_arm_unwind_sp;
- lldb::UnwindPlanSP m_unwind_plan_symbol_file_sp;
- lldb::UnwindPlanSP m_unwind_plan_fast_sp;
- lldb::UnwindPlanSP m_unwind_plan_arch_default_sp;
- lldb::UnwindPlanSP m_unwind_plan_arch_default_at_func_entry_sp;
+ std::shared_ptr<const UnwindPlan> m_unwind_plan_object_file_augmented_sp;
+ std::shared_ptr<const UnwindPlan> m_unwind_plan_eh_frame_augmented_sp;
+ std::shared_ptr<const UnwindPlan> m_unwind_plan_debug_frame_augmented_sp;
+
+ std::vector<std::shared_ptr<const UnwindPlan>> m_unwind_plan_compact_unwind;
+ std::shared_ptr<const UnwindPlan> m_unwind_plan_arm_unwind_sp;
+ std::shared_ptr<const UnwindPlan> m_unwind_plan_symbol_file_sp;
+ std::shared_ptr<const UnwindPlan> m_unwind_plan_fast_sp;
+ std::shared_ptr<const UnwindPlan> m_unwind_plan_arch_default_sp;
+ std::shared_ptr<const UnwindPlan> m_unwind_plan_arch_default_at_func_entry_sp;
// Fetching the UnwindPlans can be expensive - if we've already attempted to
// get one & failed, don't try again.
diff --git a/lldb/include/lldb/Symbol/UnwindPlan.h b/lldb/include/lldb/Symbol/UnwindPlan.h
index ddc54a9fdc8ae..80517de5a7e9c 100644
--- a/lldb/include/lldb/Symbol/UnwindPlan.h
+++ b/lldb/include/lldb/Symbol/UnwindPlan.h
@@ -464,7 +464,7 @@ class UnwindPlan {
m_return_addr_register = regnum;
}
- uint32_t GetReturnAddressRegister() { return m_return_addr_register; }
+ uint32_t GetReturnAddressRegister() const { return m_return_addr_register; }
uint32_t GetInitialCFARegister() const {
if (m_row_list.empty())
@@ -479,7 +479,7 @@ class UnwindPlan {
m_plan_valid_ranges = std::move(ranges);
}
- bool PlanValidAtAddress(Address addr);
+ bool PlanValidAtAddress(Address addr) const;
bool IsValidRowIndex(uint32_t idx) const;
diff --git a/lldb/include/lldb/Target/RegisterContextUnwind.h b/lldb/include/lldb/Target/RegisterContextUnwind.h
index 6cd918fedc003..98e25859d4eab 100644
--- a/lldb/include/lldb/Target/RegisterContextUnwind.h
+++ b/lldb/include/lldb/Target/RegisterContextUnwind.h
@@ -127,7 +127,8 @@ class RegisterContextUnwind : public lldb_private::RegisterContext {
/// Check if the given unwind plan indicates a signal trap handler, and
/// update frame type and symbol context if so.
- void PropagateTrapHandlerFlagFromUnwindPlan(lldb::UnwindPlanSP unwind_plan);
+ void PropagateTrapHandlerFlagFromUnwindPlan(
+ std::shared_ptr<const UnwindPlan> unwind_plan);
// Provide a location for where THIS function saved the CALLER's register
// value
@@ -194,16 +195,17 @@ class RegisterContextUnwind : public lldb_private::RegisterContext {
const UnwindPlan::Row::FAValue &fa,
lldb::addr_t &address);
- lldb::UnwindPlanSP GetFastUnwindPlanForFrame();
+ std::shared_ptr<const UnwindPlan> GetFastUnwindPlanForFrame();
- lldb::UnwindPlanSP GetFullUnwindPlanForFrame();
+ std::shared_ptr<const UnwindPlan> GetFullUnwindPlanForFrame();
void UnwindLogMsg(const char *fmt, ...) __attribute__((format(printf, 2, 3)));
void UnwindLogMsgVerbose(const char *fmt, ...)
__attribute__((format(printf, 2, 3)));
- bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp);
+ bool IsUnwindPlanValidForCurrentPC(
+ std::shared_ptr<const UnwindPlan> unwind_plan_sp);
lldb::addr_t GetReturnAddressHint(int32_t plan_offset);
@@ -215,9 +217,9 @@ class RegisterContextUnwind : public lldb_private::RegisterContext {
// i.e. where THIS frame saved them
///
- lldb::UnwindPlanSP m_fast_unwind_plan_sp; // may be NULL
- lldb::UnwindPlanSP m_full_unwind_plan_sp;
- lldb::UnwindPlanSP m_fallback_unwind_plan_sp; // may be NULL
+ std::shared_ptr<const UnwindPlan> m_fast_unwind_plan_sp; // may be NULL
+ std::shared_ptr<const UnwindPlan> m_full_unwind_plan_sp;
+ std::shared_ptr<const UnwindPlan> m_fallback_unwind_plan_sp; // may be NULL
bool m_all_registers_available; // Can we retrieve all regs or just
// nonvolatile regs?
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index c77bddb4af061..3f7d3007ed168 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -3641,77 +3641,70 @@ class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
result.GetOutputStream().Printf("\n");
- UnwindPlanSP non_callsite_unwind_plan =
- func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread);
- if (non_callsite_unwind_plan) {
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread)) {
result.GetOutputStream().Printf(
"Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
- non_callsite_unwind_plan->GetSourceName().AsCString());
+ plan_sp->GetSourceName().AsCString());
}
- UnwindPlanSP callsite_unwind_plan =
- func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread);
- if (callsite_unwind_plan) {
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread)) {
result.GetOutputStream().Printf(
"Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
- callsite_unwind_plan->GetSourceName().AsCString());
+ plan_sp->GetSourceName().AsCString());
}
- UnwindPlanSP fast_unwind_plan =
- func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
- if (fast_unwind_plan) {
- result.GetOutputStream().Printf(
- "Fast UnwindPlan is '%s'\n",
- fast_unwind_plan->GetSourceName().AsCString());
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread)) {
+ result.GetOutputStream().Printf("Fast UnwindPlan is '%s'\n",
+ plan_sp->GetSourceName().AsCString());
}
result.GetOutputStream().Printf("\n");
- UnwindPlanSP assembly_sp =
- func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread);
- if (assembly_sp) {
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread)) {
result.GetOutputStream().Printf(
"Assembly language inspection UnwindPlan:\n");
- assembly_sp->Dump(result.GetOutputStream(), thread.get(),
- LLDB_INVALID_ADDRESS);
+ plan_sp->Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
result.GetOutputStream().Printf("\n");
}
- UnwindPlanSP of_unwind_sp =
- func_unwinders_sp->GetObjectFileUnwindPlan(*target);
- if (of_unwind_sp) {
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ func_unwinders_sp->GetObjectFileUnwindPlan(*target)) {
result.GetOutputStream().Printf("object file UnwindPlan:\n");
- of_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
- LLDB_INVALID_ADDRESS);
+ plan_sp->Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
result.GetOutputStream().Printf("\n");
}
- UnwindPlanSP of_unwind_augmented_sp =
- func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target, *thread);
- if (of_unwind_augmented_sp) {
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target,
+ *thread)) {
result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
- of_unwind_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
- LLDB_INVALID_ADDRESS);
+ plan_sp->Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
result.GetOutputStream().Printf("\n");
}
- UnwindPlanSP ehframe_sp =
- func_unwinders_sp->GetEHFrameUnwindPlan(*target);
- if (ehframe_sp) {
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ func_unwinders_sp->GetEHFrameUnwindPlan(*target)) {
result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
- ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
- LLDB_INVALID_ADDRESS);
+ plan_sp->Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
result.GetOutputStream().Printf("\n");
}
- UnwindPlanSP ehframe_augmented_sp =
- func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread);
- if (ehframe_augmented_sp) {
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target,
+ *thread)) {
result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
- ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
- LLDB_INVALID_ADDRESS);
+ plan_sp->Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
result.GetOutputStream().Printf("\n");
}
- if (UnwindPlanSP plan_sp =
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
plan_sp->Dump(result.GetOutputStream(), thread.get(),
@@ -3719,7 +3712,7 @@ class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
result.GetOutputStream().Printf("\n");
}
- if (UnwindPlanSP plan_sp =
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
*thread)) {
result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
@@ -3728,36 +3721,35 @@ class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
result.GetOutputStream().Printf("\n");
}
- UnwindPlanSP arm_unwind_sp =
- func_unwinders_sp->GetArmUnwindUnwindPlan(*target);
- if (arm_unwind_sp) {
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ func_unwinders_sp->GetArmUnwindUnwindPlan(*target)) {
result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
- arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
- LLDB_INVALID_ADDRESS);
+ plan_sp->Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
result.GetOutputStream().Printf("\n");
}
- if (UnwindPlanSP symfile_plan_sp =
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {
result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
- symfile_plan_sp->Dump(result.GetOutputStream(), thread.get(),
- LLDB_INVALID_ADDRESS);
+ plan_sp->Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
result.GetOutputStream().Printf("\n");
}
- UnwindPlanSP compact_unwind_sp =
- func_unwinders_sp->GetCompactUnwindUnwindPlan(*target);
- if (compact_unwind_sp) {
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ func_unwinders_sp->GetCompactUnwindUnwindPlan(*target)) {
result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
- compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
- LLDB_INVALID_ADDRESS);
+ plan_sp->Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
result.GetOutputStream().Printf("\n");
}
- if (fast_unwind_plan) {
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread)) {
result.GetOutputStream().Printf("Fast UnwindPlan:\n");
- fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
- LLDB_INVALID_ADDRESS);
+ plan_sp->Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
result.GetOutputStream().Printf("\n");
}
diff --git a/lldb/source/Symbol/FuncUnwinders.cpp b/lldb/source/Symbol/FuncUnwinders.cpp
index a5ca7b094c949..a74029d8343c7 100644
--- a/lldb/source/Symbol/FuncUnwinders.cpp
+++ b/lldb/source/Symbol/FuncUnwinders.cpp
@@ -71,40 +71,47 @@ FuncUnwinders::FuncUnwinders(UnwindTable &unwind_table, Address addr,
FuncUnwinders::~FuncUnwinders() = default;
-UnwindPlanSP FuncUnwinders::GetUnwindPlanAtCallSite(Target &target,
- Thread &thread) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetUnwindPlanAtCallSite(Target &target, Thread &thread) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (UnwindPlanSP plan_sp = GetObjectFileUnwindPlan(target))
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ GetObjectFileUnwindPlan(target))
return plan_sp;
- if (UnwindPlanSP plan_sp = GetSymbolFileUnwindPlan(thread))
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ GetSymbolFileUnwindPlan(thread))
return plan_sp;
- if (UnwindPlanSP plan_sp = GetDebugFrameUnwindPlan(target))
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ GetDebugFrameUnwindPlan(target))
return plan_sp;
- if (UnwindPlanSP plan_sp = GetEHFrameUnwindPlan(target))
+ if (std::shared_ptr<const UnwindPlan> plan_sp = GetEHFrameUnwindPlan(target))
return plan_sp;
- if (UnwindPlanSP plan_sp = GetCompactUnwindUnwindPlan(target))
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ GetCompactUnwindUnwindPlan(target))
return plan_sp;
- if (UnwindPlanSP plan_sp = GetArmUnwindUnwindPlan(target))
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ GetArmUnwindUnwindPlan(target))
return plan_sp;
return nullptr;
}
-UnwindPlanSP FuncUnwinders::GetCompactUnwindUnwindPlan(Target &target) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetCompactUnwindUnwindPlan(Target &target) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_unwind_plan_compact_unwind.size() > 0)
return m_unwind_plan_compact_unwind[0]; // FIXME support multiple compact
// unwind plans for one func
if (m_tried_unwind_plan_compact_unwind)
- return UnwindPlanSP();
+ return nullptr;
m_tried_unwind_plan_compact_unwind = true;
if (m_range.GetBaseAddress().IsValid()) {
Address current_pc(m_range.GetBaseAddress());
CompactUnwindInfo *compact_unwind = m_unwind_table.GetCompactUnwindInfo();
if (compact_unwind) {
- UnwindPlanSP unwind_plan_sp(new UnwindPlan(lldb::eRegisterKindGeneric));
+ auto unwind_plan_sp =
+ std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
if (compact_unwind->GetUnwindPlan(target, current_pc, *unwind_plan_sp)) {
m_unwind_plan_compact_unwind.push_back(unwind_plan_sp);
return m_unwind_plan_compact_unwind[0]; // FIXME support multiple
@@ -113,10 +120,11 @@ UnwindPlanSP FuncUnwinders::GetCompactUnwindUnwindPlan(Target &target) {
}
}
}
- return UnwindPlanSP();
+ return nullptr;
}
-lldb::UnwindPlanSP FuncUnwinders::GetObjectFileUnwindPlan(Target &target) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetObjectFileUnwindPlan(Target &target) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_unwind_plan_object_file_sp.get() ||
m_tried_unwind_plan_object_file)
@@ -126,17 +134,16 @@ lldb::UnwindPlanSP FuncUnwinders::GetObjectFileUnwindPlan(Target &target) {
if (m_range.GetBaseAddress().IsValid()) {
CallFrameInfo *object_file_frame = m_unwind_table.GetObjectFileUnwindInfo();
if (object_file_frame) {
- m_unwind_plan_object_file_sp =
- std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
- if (!object_file_frame->GetUnwindPlan(m_range,
- *m_unwind_plan_object_file_sp))
- m_unwind_plan_object_file_sp.reset();
+ auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+ if (object_file_frame->GetUnwindPlan(m_range, *plan_sp))
+ m_unwind_plan_object_file_sp = std::move(plan_sp);
}
}
return m_unwind_plan_object_file_sp;
}
-UnwindPlanSP FuncUnwinders::GetEHFrameUnwindPlan(Target &target) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetEHFrameUnwindPlan(Target &target) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_unwind_plan_eh_frame_sp.get() || m_tried_unwind_plan_eh_frame)
return m_unwind_plan_eh_frame_sp;
@@ -145,16 +152,16 @@ UnwindPlanSP FuncUnwinders::GetEHFrameUnwindPlan(Target &target) {
if (m_range.GetBaseAddress().IsValid()) {
DWARFCallFrameInfo *eh_frame = m_unwind_table.GetEHFrameInfo();
if (eh_frame) {
- m_unwind_plan_eh_frame_sp =
- std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
- if (!eh_frame->GetUnwindPlan(m_range, *m_unwind_plan_eh_frame_sp))
- m_unwind_plan_eh_frame_sp.reset();
+ auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+ if (eh_frame->GetUnwindPlan(m_range, *plan_sp))
+ m_unwind_plan_eh_frame_sp = std::move(plan_sp);
}
}
return m_unwind_plan_eh_frame_sp;
}
-UnwindPlanSP FuncUnwinders::GetDebugFrameUnwindPlan(Target &target) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetDebugFrameUnwindPlan(Target &target) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_unwind_plan_debug_frame_sp || m_tried_unwind_plan_debug_frame)
return m_unwind_plan_debug_frame_sp;
@@ -163,16 +170,16 @@ UnwindPlanSP FuncUnwinders::GetDebugFrameUnwindPlan(Target &target) {
if (m_range.GetBaseAddress().IsValid()) {
DWARFCallFrameInfo *debug_frame = m_unwind_table.GetDebugFrameInfo();
if (debug_frame) {
- m_unwind_plan_debug_frame_sp =
- std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
- if (!debug_frame->GetUnwindPlan(m_range, *m_unwind_plan_debug_frame_sp))
- m_unwind_plan_debug_frame_sp.reset();
+ auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+ if (debug_frame->GetUnwindPlan(m_range, *plan_sp))
+ m_unwind_plan_debug_frame_sp = std::move(plan_sp);
}
}
return m_unwind_plan_debug_frame_sp;
}
-UnwindPlanSP FuncUnwinders::GetArmUnwindUnwindPlan(Target &target) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetArmUnwindUnwindPlan(Target &target) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_unwind_plan_arm_unwind_sp.get() || m_tried_unwind_plan_arm_unwind)
return m_unwind_plan_arm_unwind_sp;
@@ -182,11 +189,9 @@ UnwindPlanSP FuncUnwinders::GetArmUnwindUnwindPlan(Target &target) {
Address current_pc(m_range.GetBaseAddress());
ArmUnwindInfo *arm_unwind_info = m_unwind_table.GetArmUnwindInfo();
if (arm_unwind_info) {
- m_unwind_plan_arm_unwind_sp =
- std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
- if (!arm_unwind_info->GetUnwindPlan(target, current_pc,
- *m_unwind_plan_arm_unwind_sp))
- m_unwind_plan_arm_unwind_sp.reset();
+ auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+ if (arm_unwind_info->GetUnwindPlan(target, current_pc, *plan_sp))
+ m_unwind_plan_arm_unwind_sp = std::move(plan_sp);
}
}
return m_unwind_plan_arm_unwind_sp;
@@ -210,7 +215,8 @@ class RegisterContextToInfo: public SymbolFile::RegisterInfoResolver {
};
} // namespace
-UnwindPlanSP FuncUnwinders::GetSymbolFileUnwindPlan(Thread &thread) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetSymbolFileUnwindPlan(Thread &thread) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_unwind_plan_symbol_file_sp.get() || m_tried_unwind_plan_symbol_file)
return m_unwind_plan_symbol_file_sp;
@@ -224,9 +230,9 @@ UnwindPlanSP FuncUnwinders::GetSymbolFileUnwindPlan(Thread &thread) {
return m_unwind_plan_symbol_file_sp;
}
-UnwindPlanSP
+std::shared_ptr<const UnwindPlan>
FuncUnwinders::GetObjectFileAugmentedUnwindPlan(Target &target,
- Thread &thread) {
+ Thread &thread) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_unwind_plan_object_file_augmented_sp.get() ||
m_tried_unwind_plan_object_file_augmented)
@@ -234,30 +240,27 @@ FuncUnwinders::GetObjectFileAugmentedUnwindPlan(Target &target,
m_tried_unwind_plan_object_file_augmented = true;
- UnwindPlanSP object_file_unwind_plan = GetObjectFileUnwindPlan(target);
+ std::shared_ptr<const UnwindPlan> object_file_unwind_plan =
+ GetObjectFileUnwindPlan(target);
if (!object_file_unwind_plan)
return m_unwind_plan_object_file_augmented_sp;
- m_unwind_plan_object_file_augmented_sp =
- std::make_shared<UnwindPlan>(*object_file_unwind_plan);
-
// Augment the instructions with epilogue descriptions if necessary
// so the UnwindPlan can be used at any instruction in the function.
UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
if (assembly_profiler_sp) {
- if (!assembly_profiler_sp->AugmentUnwindPlanFromCallSite(
- m_range, thread, *m_unwind_plan_object_file_augmented_sp)) {
- m_unwind_plan_object_file_augmented_sp.reset();
- }
- } else {
- m_unwind_plan_object_file_augmented_sp.reset();
+ auto plan_sp = std::make_shared<UnwindPlan>(*object_file_unwind_plan);
+
+ if (assembly_profiler_sp->AugmentUnwindPlanFromCallSite(m_range, thread,
+ *plan_sp))
+ m_unwind_plan_object_file_augmented_sp = std::move(plan_sp);
}
return m_unwind_plan_object_file_augmented_sp;
}
-UnwindPlanSP FuncUnwinders::GetEHFrameAugmentedUnwindPlan(Target &target,
- Thread &thread) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetEHFrameAugmentedUnwindPlan(Target &target, Thread &thread) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_unwind_plan_eh_frame_augmented_sp.get() ||
m_tried_unwind_plan_eh_frame_augmented)
@@ -275,30 +278,27 @@ UnwindPlanSP FuncUnwinders::GetEHFrameAugmentedUnwindPlan(Target &target,
m_tried_unwind_plan_eh_frame_augmented = true;
- UnwindPlanSP eh_frame_plan = GetEHFrameUnwindPlan(target);
+ std::shared_ptr<const UnwindPlan> eh_frame_plan =
+ GetEHFrameUnwindPlan(target);
if (!eh_frame_plan)
return m_unwind_plan_eh_frame_augmented_sp;
- m_unwind_plan_eh_frame_augmented_sp =
- std::make_shared<UnwindPlan>(*eh_frame_plan);
-
// Augment the eh_frame instructions with epilogue descriptions if necessary
// so the UnwindPlan can be used at any instruction in the function.
UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
if (assembly_profiler_sp) {
- if (!assembly_profiler_sp->AugmentUnwindPlanFromCallSite(
- m_range, thread, *m_unwind_plan_eh_frame_augmented_sp)) {
- m_unwind_plan_eh_frame_augmented_sp.reset();
- }
- } else {
- m_unwind_plan_eh_frame_augmented_sp.reset();
+ auto plan_sp = std::make_shared<UnwindPlan>(*eh_frame_plan);
+ if (assembly_profiler_sp->AugmentUnwindPlanFromCallSite(m_range, thread,
+ *plan_sp))
+ m_unwind_plan_eh_frame_augmented_sp = std::move(plan_sp);
}
return m_unwind_plan_eh_frame_augmented_sp;
}
-UnwindPlanSP FuncUnwinders::GetDebugFrameAugmentedUnwindPlan(Target &target,
- Thread &thread) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetDebugFrameAugmentedUnwindPlan(Target &target,
+ Thread &thread) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_unwind_plan_debug_frame_augmented_sp.get() ||
m_tried_unwind_plan_debug_frame_augmented)
@@ -316,30 +316,28 @@ UnwindPlanSP FuncUnwinders::GetDebugFrameAugmentedUnwindPlan(Target &target,
m_tried_unwind_plan_debug_frame_augmented = true;
- UnwindPlanSP debug_frame_plan = GetDebugFrameUnwindPlan(target);
+ std::shared_ptr<const UnwindPlan> debug_frame_plan =
+ GetDebugFrameUnwindPlan(target);
if (!debug_frame_plan)
return m_unwind_plan_debug_frame_augmented_sp;
- m_unwind_plan_debug_frame_augmented_sp =
- std::make_shared<UnwindPlan>(*debug_frame_plan);
-
// Augment the debug_frame instructions with epilogue descriptions if
// necessary so the UnwindPlan can be used at any instruction in the
// function.
UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
if (assembly_profiler_sp) {
- if (!assembly_profiler_sp->AugmentUnwindPlanFromCallSite(
- m_range, thread, *m_unwind_plan_debug_frame_augmented_sp)) {
- m_unwind_plan_debug_frame_augmented_sp.reset();
- }
- } else
- m_unwind_plan_debug_frame_augmented_sp.reset();
+ auto plan_sp = std::make_shared<UnwindPlan>(*debug_frame_plan);
+
+ if (assembly_profiler_sp->AugmentUnwindPlanFromCallSite(m_range, thread,
+ *plan_sp))
+ m_unwind_plan_debug_frame_augmented_sp = std::move(plan_sp);
+ }
return m_unwind_plan_debug_frame_augmented_sp;
}
-UnwindPlanSP FuncUnwinders::GetAssemblyUnwindPlan(Target &target,
- Thread &thread) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetAssemblyUnwindPlan(Target &target, Thread &thread) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_unwind_plan_assembly_sp.get() || m_tried_unwind_plan_assembly ||
!m_unwind_table.GetAllowAssemblyEmulationUnwindPlans()) {
@@ -360,12 +358,10 @@ UnwindPlanSP FuncUnwinders::GetAssemblyUnwindPlan(Target &target,
UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
if (assembly_profiler_sp) {
- m_unwind_plan_assembly_sp =
- std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
- if (!assembly_profiler_sp->GetNonCallSiteUnwindPlanFromAssembly(
- range, thread, *m_unwind_plan_assembly_sp)) {
- m_unwind_plan_assembly_sp.reset();
- }
+ auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+ if (assembly_profiler_sp->GetNonCallSiteUnwindPlanFromAssembly(
+ range, thread, *plan_sp))
+ m_unwind_plan_assembly_sp = std::move(plan_sp);
}
return m_unwind_plan_assembly_sp;
}
@@ -374,7 +370,8 @@ UnwindPlanSP FuncUnwinders::GetAssemblyUnwindPlan(Target &target,
// If they have the same way of getting the pc value (e.g. "CFA - 8" + "CFA is
// sp"), then it will return LazyBoolTrue.
LazyBool FuncUnwinders::CompareUnwindPlansForIdenticalInitialPCLocation(
- Thread &thread, const UnwindPlanSP &a, const UnwindPlanSP &b) {
+ Thread &thread, const std::shared_ptr<const UnwindPlan> &a,
+ const std::shared_ptr<const UnwindPlan> &b) {
LazyBool plans_are_identical = eLazyBoolCalculate;
RegisterNumber pc_reg(thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
@@ -404,17 +401,19 @@ LazyBool FuncUnwinders::CompareUnwindPlansForIdenticalInitialPCLocation(
return plans_are_identical;
}
-UnwindPlanSP FuncUnwinders::GetUnwindPlanAtNonCallSite(Target &target,
- Thread &thread) {
- UnwindPlanSP eh_frame_sp = GetEHFrameUnwindPlan(target);
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetUnwindPlanAtNonCallSite(Target &target, Thread &thread) {
+ std::shared_ptr<const UnwindPlan> eh_frame_sp = GetEHFrameUnwindPlan(target);
if (!eh_frame_sp)
eh_frame_sp = GetDebugFrameUnwindPlan(target);
if (!eh_frame_sp)
eh_frame_sp = GetObjectFileUnwindPlan(target);
- UnwindPlanSP arch_default_at_entry_sp =
+ std::shared_ptr<const UnwindPlan> arch_default_at_entry_sp =
GetUnwindPlanArchitectureDefaultAtFunctionEntry(thread);
- UnwindPlanSP arch_default_sp = GetUnwindPlanArchitectureDefault(thread);
- UnwindPlanSP assembly_sp = GetAssemblyUnwindPlan(target, thread);
+ std::shared_ptr<const UnwindPlan> arch_default_sp =
+ GetUnwindPlanArchitectureDefault(thread);
+ std::shared_ptr<const UnwindPlan> assembly_sp =
+ GetAssemblyUnwindPlan(target, thread);
// This point of this code is to detect when a function is using a non-
// standard ABI, and the eh_frame correctly describes that alternate ABI.
@@ -443,20 +442,24 @@ UnwindPlanSP FuncUnwinders::GetUnwindPlanAtNonCallSite(Target &target,
return eh_frame_sp;
}
- if (UnwindPlanSP plan_sp = GetSymbolFileUnwindPlan(thread))
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ GetSymbolFileUnwindPlan(thread))
return plan_sp;
- if (UnwindPlanSP plan_sp = GetDebugFrameAugmentedUnwindPlan(target, thread))
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ GetDebugFrameAugmentedUnwindPlan(target, thread))
return plan_sp;
- if (UnwindPlanSP plan_sp = GetEHFrameAugmentedUnwindPlan(target, thread))
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ GetEHFrameAugmentedUnwindPlan(target, thread))
return plan_sp;
- if (UnwindPlanSP plan_sp = GetObjectFileAugmentedUnwindPlan(target, thread))
+ if (std::shared_ptr<const UnwindPlan> plan_sp =
+ GetObjectFileAugmentedUnwindPlan(target, thread))
return plan_sp;
return assembly_sp;
}
-UnwindPlanSP FuncUnwinders::GetUnwindPlanFastUnwind(Target &target,
- Thread &thread) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetUnwindPlanFastUnwind(Target &target, Thread &thread) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_unwind_plan_fast_sp.get() || m_tried_unwind_fast)
return m_unwind_plan_fast_sp;
@@ -465,17 +468,15 @@ UnwindPlanSP FuncUnwinders::GetUnwindPlanFastUnwind(Target &target,
UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
if (assembly_profiler_sp) {
- m_unwind_plan_fast_sp =
- std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
- if (!assembly_profiler_sp->GetFastUnwindPlan(m_range, thread,
- *m_unwind_plan_fast_sp)) {
- m_unwind_plan_fast_sp.reset();
- }
+ auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+ if (assembly_profiler_sp->GetFastUnwindPlan(m_range, thread, *plan_sp))
+ m_unwind_plan_fast_sp = std::move(plan_sp);
}
return m_unwind_plan_fast_sp;
}
-UnwindPlanSP FuncUnwinders::GetUnwindPlanArchitectureDefault(Thread &thread) {
+std::shared_ptr<const UnwindPlan>
+FuncUnwinders::GetUnwindPlanArchitectureDefault(Thread &thread) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_unwind_plan_arch_default_sp.get() || m_tried_unwind_arch_default)
return m_unwind_plan_arch_default_sp;
@@ -491,7 +492,7 @@ UnwindPlanSP FuncUnwinders::GetUnwindPlanArchitectureDefault(Thread &thread) {
return m_unwind_plan_arch_default_sp;
}
-UnwindPlanSP
+std::shared_ptr<const UnwindPlan>
FuncUnwinders::GetUnwindPlanArchitectureDefaultAtFunctionEntry(Thread &thread) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (m_unwind_plan_arch_default_at_func_entry_sp.get() ||
@@ -540,7 +541,8 @@ FuncUnwinders::GetUnwindAssemblyProfiler(Target &target) {
Address FuncUnwinders::GetLSDAAddress(Target &target) {
Address lsda_addr;
- UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan(target);
+ std::shared_ptr<const UnwindPlan> unwind_plan_sp =
+ GetEHFrameUnwindPlan(target);
if (unwind_plan_sp.get() == nullptr) {
unwind_plan_sp = GetCompactUnwindUnwindPlan(target);
}
@@ -556,7 +558,8 @@ Address FuncUnwinders::GetLSDAAddress(Target &target) {
Address FuncUnwinders::GetPersonalityRoutinePtrAddress(Target &target) {
Address personality_addr;
- UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan(target);
+ std::shared_ptr<const UnwindPlan> unwind_plan_sp =
+ GetEHFrameUnwindPlan(target);
if (unwind_plan_sp.get() == nullptr) {
unwind_plan_sp = GetCompactUnwindUnwindPlan(target);
}
diff --git a/lldb/source/Symbol/UnwindPlan.cpp b/lldb/source/Symbol/UnwindPlan.cpp
index 92daf29630ab6..14b2c1ce2f227 100644
--- a/lldb/source/Symbol/UnwindPlan.cpp
+++ b/lldb/source/Symbol/UnwindPlan.cpp
@@ -450,7 +450,7 @@ const UnwindPlan::Row *UnwindPlan::GetLastRow() const {
return &m_row_list.back();
}
-bool UnwindPlan::PlanValidAtAddress(Address addr) {
+bool UnwindPlan::PlanValidAtAddress(Address addr) const {
// If this UnwindPlan has no rows, it is an invalid UnwindPlan.
if (GetRowCount() == 0) {
Log *log = GetLog(LLDBLog::Unwind);
diff --git a/lldb/source/Target/RegisterContextUnwind.cpp b/lldb/source/Target/RegisterContextUnwind.cpp
index a035c57fbfc1c..48d1c887ff430 100644
--- a/lldb/source/Target/RegisterContextUnwind.cpp
+++ b/lldb/source/Target/RegisterContextUnwind.cpp
@@ -84,7 +84,7 @@ RegisterContextUnwind::RegisterContextUnwind(Thread &thread,
}
bool RegisterContextUnwind::IsUnwindPlanValidForCurrentPC(
- lldb::UnwindPlanSP unwind_plan_sp) {
+ std::shared_ptr<const UnwindPlan> unwind_plan_sp) {
if (!unwind_plan_sp)
return false;
@@ -140,8 +140,9 @@ void RegisterContextUnwind::InitializeZerothFrame() {
if (ABISP abi_sp = process->GetABI())
current_pc = abi_sp->FixCodeAddress(current_pc);
- UnwindPlanSP lang_runtime_plan_sp = LanguageRuntime::GetRuntimeUnwindPlan(
- m_thread, this, m_behaves_like_zeroth_frame);
+ std::shared_ptr<const UnwindPlan> lang_runtime_plan_sp =
+ LanguageRuntime::GetRuntimeUnwindPlan(m_thread, this,
+ m_behaves_like_zeroth_frame);
if (lang_runtime_plan_sp.get()) {
UnwindLogMsg("This is an async frame");
}
@@ -264,7 +265,7 @@ void RegisterContextUnwind::InitializeZerothFrame() {
// Try the fall back unwind plan since the
// full unwind plan failed.
FuncUnwindersSP func_unwinders_sp;
- UnwindPlanSP call_site_unwind_plan;
+ std::shared_ptr<const UnwindPlan> call_site_unwind_plan;
bool cfa_status = false;
if (m_sym_ctx_valid) {
@@ -339,8 +340,9 @@ void RegisterContextUnwind::InitializeNonZerothFrame() {
// A LanguageRuntime may provide an UnwindPlan that is used in this
// stack trace base on the RegisterContext contents, intsead
// of the normal UnwindPlans we would use for the return-pc.
- UnwindPlanSP lang_runtime_plan_sp = LanguageRuntime::GetRuntimeUnwindPlan(
- m_thread, this, m_behaves_like_zeroth_frame);
+ std::shared_ptr<const UnwindPlan> lang_runtime_plan_sp =
+ LanguageRuntime::GetRuntimeUnwindPlan(m_thread, this,
+ m_behaves_like_zeroth_frame);
if (lang_runtime_plan_sp.get()) {
UnwindLogMsg("This is an async frame");
}
@@ -748,39 +750,37 @@ bool RegisterContextUnwind::BehavesLikeZerothFrame() const {
// 4. m_current_offset_backed_up_one should have the current byte offset into
// the function, maybe backed up by 1, -1 if unknown
-UnwindPlanSP RegisterContextUnwind::GetFastUnwindPlanForFrame() {
- UnwindPlanSP unwind_plan_sp;
+std::shared_ptr<const UnwindPlan>
+RegisterContextUnwind::GetFastUnwindPlanForFrame() {
ModuleSP pc_module_sp(m_current_pc.GetModule());
if (!m_current_pc.IsValid() || !pc_module_sp ||
pc_module_sp->GetObjectFile() == nullptr)
- return unwind_plan_sp;
+ return nullptr;
if (IsFrameZero())
- return unwind_plan_sp;
+ return nullptr;
FuncUnwindersSP func_unwinders_sp(
pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress(
m_current_pc, m_sym_ctx));
if (!func_unwinders_sp)
- return unwind_plan_sp;
+ return nullptr;
// If we're in _sigtramp(), unwinding past this frame requires special
// knowledge.
if (m_frame_type == eTrapHandlerFrame || m_frame_type == eDebuggerFrame)
- return unwind_plan_sp;
+ return nullptr;
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind(
- *m_thread.CalculateTarget(), m_thread);
- if (unwind_plan_sp) {
+ if (std::shared_ptr<const UnwindPlan> unwind_plan_sp =
+ func_unwinders_sp->GetUnwindPlanFastUnwind(
+ *m_thread.CalculateTarget(), m_thread)) {
if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
m_frame_type = eNormalFrame;
return unwind_plan_sp;
- } else {
- unwind_plan_sp.reset();
}
}
- return unwind_plan_sp;
+ return nullptr;
}
// On entry to this method,
@@ -792,9 +792,9 @@ UnwindPlanSP RegisterContextUnwind::GetFastUnwindPlanForFrame() {
// 4. m_current_offset_backed_up_one should have the current byte offset into
// the function, maybe backed up by 1, -1 if unknown
-UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
- UnwindPlanSP unwind_plan_sp;
- UnwindPlanSP arch_default_unwind_plan_sp;
+std::shared_ptr<const UnwindPlan>
+RegisterContextUnwind::GetFullUnwindPlanForFrame() {
+ std::shared_ptr<const UnwindPlan> arch_default_unwind_plan_sp;
ExecutionContext exe_ctx(m_thread.shared_from_this());
Process *process = exe_ctx.GetProcessPtr();
ABI *abi = process ? process->GetABI().get() : nullptr;
@@ -832,9 +832,8 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
process->GetLoadAddressPermissions(current_pc_addr, permissions) &&
(permissions & ePermissionsExecutable) == 0)) {
if (abi) {
- unwind_plan_sp = abi->CreateFunctionEntryUnwindPlan();
m_frame_type = eNormalFrame;
- return unwind_plan_sp;
+ return abi->CreateFunctionEntryUnwindPlan();
}
}
}
@@ -871,32 +870,29 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
DWARFCallFrameInfo *eh_frame =
pc_module_sp->GetUnwindTable().GetEHFrameInfo();
if (eh_frame) {
- unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+ auto unwind_plan_sp =
+ std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
if (eh_frame->GetUnwindPlan(m_current_pc, *unwind_plan_sp))
return unwind_plan_sp;
- else
- unwind_plan_sp.reset();
}
ArmUnwindInfo *arm_exidx =
pc_module_sp->GetUnwindTable().GetArmUnwindInfo();
if (arm_exidx) {
- unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+ auto unwind_plan_sp =
+ std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
if (arm_exidx->GetUnwindPlan(exe_ctx.GetTargetRef(), m_current_pc,
*unwind_plan_sp))
return unwind_plan_sp;
- else
- unwind_plan_sp.reset();
}
CallFrameInfo *object_file_unwind =
pc_module_sp->GetUnwindTable().GetObjectFileUnwindInfo();
if (object_file_unwind) {
- unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+ auto unwind_plan_sp =
+ std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
if (object_file_unwind->GetUnwindPlan(m_current_pc, *unwind_plan_sp))
return unwind_plan_sp;
- else
- unwind_plan_sp.reset();
}
return arch_default_unwind_plan_sp;
@@ -910,15 +906,13 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
// substitute plan. Otherwise, use eh_frame.
if (m_sym_ctx_valid) {
lldb::PlatformSP platform = process->GetTarget().GetPlatform();
- unwind_plan_sp = platform->GetTrapHandlerUnwindPlan(
- process->GetTarget().GetArchitecture().GetTriple(),
- GetSymbolOrFunctionName(m_sym_ctx));
-
- if (unwind_plan_sp)
+ if (auto unwind_plan_sp = platform->GetTrapHandlerUnwindPlan(
+ process->GetTarget().GetArchitecture().GetTriple(),
+ GetSymbolOrFunctionName(m_sym_ctx)))
return unwind_plan_sp;
}
- unwind_plan_sp =
+ auto unwind_plan_sp =
func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget());
if (!unwind_plan_sp)
unwind_plan_sp =
@@ -943,7 +937,7 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
// normally we would call GetUnwindPlanAtCallSite() -- because CallSite may
// return an unwind plan sourced from either eh_frame (that's what we
// intend) or compact unwind (this won't work)
- unwind_plan_sp =
+ auto unwind_plan_sp =
func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget());
if (!unwind_plan_sp)
unwind_plan_sp =
@@ -959,7 +953,7 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
// Typically the NonCallSite UnwindPlan is the unwind created by inspecting
// the assembly language instructions
if (m_behaves_like_zeroth_frame && process) {
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
+ auto unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
process->GetTarget(), m_thread);
if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
if (unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) {
@@ -974,7 +968,7 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
// assembly code it is often written in a way that it valid at all
// location what helps in the most common cases when the instruction
// emulation fails.
- UnwindPlanSP call_site_unwind_plan =
+ std::shared_ptr<const UnwindPlan> call_site_unwind_plan =
func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(),
m_thread);
if (call_site_unwind_plan &&
@@ -1009,6 +1003,7 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
}
}
+ std::shared_ptr<const UnwindPlan> unwind_plan_sp;
// Typically this is unwind info from an eh_frame section intended for
// exception handling; only valid at call sites
if (process) {
@@ -1041,7 +1036,7 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
// sites then the architecture default plan and for hand written assembly
// code it is often written in a way that it valid at all location what
// helps in the most common cases when the instruction emulation fails.
- UnwindPlanSP call_site_unwind_plan =
+ std::shared_ptr<const UnwindPlan> call_site_unwind_plan =
func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(),
m_thread);
if (call_site_unwind_plan &&
@@ -1785,7 +1780,8 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() {
// Switch the full UnwindPlan to be the fallback UnwindPlan. If we decide
// this isn't working, we need to restore. We'll also need to save & restore
// the value of the m_cfa ivar. Save is down below a bit in 'old_cfa'.
- UnwindPlanSP original_full_unwind_plan_sp = m_full_unwind_plan_sp;
+ std::shared_ptr<const UnwindPlan> original_full_unwind_plan_sp =
+ m_full_unwind_plan_sp;
addr_t old_cfa = m_cfa;
addr_t old_afa = m_afa;
@@ -1914,7 +1910,7 @@ bool RegisterContextUnwind::ForceSwitchToFallbackUnwindPlan() {
}
void RegisterContextUnwind::PropagateTrapHandlerFlagFromUnwindPlan(
- lldb::UnwindPlanSP unwind_plan) {
+ std::shared_ptr<const UnwindPlan> unwind_plan) {
if (unwind_plan->GetUnwindPlanForSignalTrap() != eLazyBoolYes) {
// Unwind plan does not indicate trap handler. Do nothing. We may
// already be flagged as trap handler flag due to the symbol being
>From 218d7ec4e7743ed9a16b94a5adb0aae11da62652 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Thu, 27 Mar 2025 14:36:10 +0100
Subject: [PATCH 2/2] [lldb] Make GetRowForFunctionOffset compatible with
discontinuous functions
The function had special handling for -1, but that is incompatible with
functions whose entry point is not the first address. Use std::nullopt
instead.
---
lldb/include/lldb/Symbol/UnwindPlan.h | 11 ++++----
.../lldb/Target/RegisterContextUnwind.h | 21 ++++++++--------
lldb/source/Symbol/UnwindPlan.cpp | 7 +++---
lldb/source/Target/RegisterContextUnwind.cpp | 25 ++++++++++---------
4 files changed, 33 insertions(+), 31 deletions(-)
diff --git a/lldb/include/lldb/Symbol/UnwindPlan.h b/lldb/include/lldb/Symbol/UnwindPlan.h
index 80517de5a7e9c..0feb20b12e184 100644
--- a/lldb/include/lldb/Symbol/UnwindPlan.h
+++ b/lldb/include/lldb/Symbol/UnwindPlan.h
@@ -450,11 +450,12 @@ class UnwindPlan {
void InsertRow(Row row, bool replace_existing = false);
// Returns a pointer to the best row for the given offset into the function's
- // instructions. If offset is -1 it indicates that the function start is
- // unknown - the final row in the UnwindPlan is returned. In practice, the
- // UnwindPlan for a function with no known start address will be the
- // architectural default UnwindPlan which will only have one row.
- const UnwindPlan::Row *GetRowForFunctionOffset(int offset) const;
+ // instructions. If offset is std::nullopt it indicates that the function
+ // start is unknown - the final row in the UnwindPlan is returned. In
+ // practice, the UnwindPlan for a function with no known start address will be
+ // the architectural default UnwindPlan which will only have one row.
+ const UnwindPlan::Row *
+ GetRowForFunctionOffset(std::optional<int> offset) const;
lldb::RegisterKind GetRegisterKind() const { return m_register_kind; }
diff --git a/lldb/include/lldb/Target/RegisterContextUnwind.h b/lldb/include/lldb/Target/RegisterContextUnwind.h
index 98e25859d4eab..044a387fe5aa2 100644
--- a/lldb/include/lldb/Target/RegisterContextUnwind.h
+++ b/lldb/include/lldb/Target/RegisterContextUnwind.h
@@ -230,18 +230,17 @@ class RegisterContextUnwind : public lldb_private::RegisterContext {
lldb_private::Address m_start_pc;
lldb_private::Address m_current_pc;
- int m_current_offset; // how far into the function we've executed; -1 if
- // unknown
- // 0 if no instructions have been executed yet.
-
- // 0 if no instructions have been executed yet.
- // On architectures where the return address on the stack points
- // to the instruction after the CALL, this value will have 1
- // subtracted from it. Else a function that ends in a CALL will
- // have an offset pointing into the next function's address range.
+ /// How far into the function we've executed. 0 if no instructions have been
+ /// executed yet, std::nullopt if unknown.
+ std::optional<int> m_current_offset;
+
+ // How far into the function we've executed. 0 if no instructions have been
+ // executed yet, std::nullopt if unknown. On architectures where the return
+ // address on the stack points to the instruction after the CALL, this value
+ // will have 1 subtracted from it. Otherwise, a function that ends in a CALL
+ // will have an offset pointing into the next function's address range.
// m_current_pc has the actual address of the "current" pc.
- int m_current_offset_backed_up_one; // how far into the function we've
- // executed; -1 if unknown
+ std::optional<int> m_current_offset_backed_up_one;
bool m_behaves_like_zeroth_frame; // this frame behaves like frame zero
diff --git a/lldb/source/Symbol/UnwindPlan.cpp b/lldb/source/Symbol/UnwindPlan.cpp
index 14b2c1ce2f227..48999aadab1e2 100644
--- a/lldb/source/Symbol/UnwindPlan.cpp
+++ b/lldb/source/Symbol/UnwindPlan.cpp
@@ -417,9 +417,10 @@ void UnwindPlan::InsertRow(Row row, bool replace_existing) {
}
}
-const UnwindPlan::Row *UnwindPlan::GetRowForFunctionOffset(int offset) const {
- auto it = offset == -1 ? m_row_list.end()
- : llvm::upper_bound(m_row_list, offset, RowLess());
+const UnwindPlan::Row *
+UnwindPlan::GetRowForFunctionOffset(std::optional<int> offset) const {
+ auto it = offset ? llvm::upper_bound(m_row_list, *offset, RowLess())
+ : m_row_list.end();
if (it == m_row_list.begin())
return nullptr;
// upper_bound returns the row strictly greater than our desired offset, which
diff --git a/lldb/source/Target/RegisterContextUnwind.cpp b/lldb/source/Target/RegisterContextUnwind.cpp
index 48d1c887ff430..b6a4a71bc3356 100644
--- a/lldb/source/Target/RegisterContextUnwind.cpp
+++ b/lldb/source/Target/RegisterContextUnwind.cpp
@@ -94,8 +94,9 @@ bool RegisterContextUnwind::IsUnwindPlanValidForCurrentPC(
return true;
}
- // if m_current_offset <= 0, we've got nothing else to try
- if (m_current_offset <= 0)
+ // If don't have an offset or we're at the start of the function, we've got
+ // nothing else to try.
+ if (!m_current_offset || m_current_offset == 0)
return false;
// check pc - 1 to see if it's valid
@@ -199,8 +200,8 @@ void RegisterContextUnwind::InitializeZerothFrame() {
m_current_offset_backed_up_one = m_current_offset;
} else {
m_start_pc = m_current_pc;
- m_current_offset = -1;
- m_current_offset_backed_up_one = -1;
+ m_current_offset = std::nullopt;
+ m_current_offset_backed_up_one = std::nullopt;
}
// We've set m_frame_type and m_sym_ctx before these calls.
@@ -439,8 +440,8 @@ void RegisterContextUnwind::InitializeNonZerothFrame() {
m_frame_type = eNormalFrame;
}
m_all_registers_available = false;
- m_current_offset = -1;
- m_current_offset_backed_up_one = -1;
+ m_current_offset = std::nullopt;
+ m_current_offset_backed_up_one = std::nullopt;
RegisterKind row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
if (const UnwindPlan::Row *row =
m_full_unwind_plan_sp->GetRowForFunctionOffset(0)) {
@@ -571,16 +572,16 @@ void RegisterContextUnwind::InitializeNonZerothFrame() {
m_current_offset = pc - m_start_pc.GetLoadAddress(&process->GetTarget());
m_current_offset_backed_up_one = m_current_offset;
if (decr_pc_and_recompute_addr_range &&
- m_current_offset_backed_up_one > 0) {
- m_current_offset_backed_up_one--;
+ m_current_offset_backed_up_one != 0) {
+ --*m_current_offset_backed_up_one;
if (m_sym_ctx_valid) {
m_current_pc.SetLoadAddress(pc - 1, &process->GetTarget());
}
}
} else {
m_start_pc = m_current_pc;
- m_current_offset = -1;
- m_current_offset_backed_up_one = -1;
+ m_current_offset = std::nullopt;
+ m_current_offset_backed_up_one = std::nullopt;
}
if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
@@ -748,7 +749,7 @@ bool RegisterContextUnwind::BehavesLikeZerothFrame() const {
// 2. m_sym_ctx should already be filled in, and
// 3. m_current_pc should have the current pc value for this frame
// 4. m_current_offset_backed_up_one should have the current byte offset into
-// the function, maybe backed up by 1, -1 if unknown
+// the function, maybe backed up by 1, std::nullopt if unknown
std::shared_ptr<const UnwindPlan>
RegisterContextUnwind::GetFastUnwindPlanForFrame() {
@@ -790,7 +791,7 @@ RegisterContextUnwind::GetFastUnwindPlanForFrame() {
// 2. m_sym_ctx should already be filled in, and
// 3. m_current_pc should have the current pc value for this frame
// 4. m_current_offset_backed_up_one should have the current byte offset into
-// the function, maybe backed up by 1, -1 if unknown
+// the function, maybe backed up by 1, std::nullopt if unknown
std::shared_ptr<const UnwindPlan>
RegisterContextUnwind::GetFullUnwindPlanForFrame() {
More information about the lldb-commits
mailing list