labath created this revision.
labath added reviewers: jasonmolenda, clayborg.
Previous patch (r360409) introduced the "symbol file unwind plan"
concept, but that plan wasn't used for unwinding yet. With this patch,
we start to consider the new plan as a possible strategy for both
synchronous and asynchronous unwinding. I also add a test that asserts
that unwinding via breakpad STACK CFI info works end-to-end.
https://reviews.llvm.org/D61853
Files:
include/lldb/Symbol/FuncUnwinders.h
lit/SymbolFile/Breakpad/Inputs/unwind-via-stack-cfi.dmp
lit/SymbolFile/Breakpad/Inputs/unwind-via-stack-cfi.syms
lit/SymbolFile/Breakpad/stack-cfi-parsing.test
lit/SymbolFile/Breakpad/unwind-via-stack-cfi.test
source/Commands/CommandObjectTarget.cpp
source/Plugins/Process/Utility/RegisterContextLLDB.cpp
source/Symbol/FuncUnwinders.cpp
Index: source/Symbol/FuncUnwinders.cpp
===================================================================
--- source/Symbol/FuncUnwinders.cpp
+++ source/Symbol/FuncUnwinders.cpp
@@ -54,7 +54,8 @@
FuncUnwinders::~FuncUnwinders() {}
-UnwindPlanSP FuncUnwinders::GetUnwindPlanAtCallSite(Target &target) {
+UnwindPlanSP FuncUnwinders::GetUnwindPlanAtCallSite(Target &target,
+ Thread &thread) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (UnwindPlanSP plan_sp = GetEHFrameUnwindPlan(target))
@@ -65,6 +66,8 @@
return plan_sp;
if (UnwindPlanSP plan_sp = GetArmUnwindUnwindPlan(target))
return plan_sp;
+ if (UnwindPlanSP plan_sp = GetSymbolFileUnwindPlan(thread))
+ return plan_sp;
return nullptr;
}
@@ -361,6 +364,8 @@
return plan_sp;
if (UnwindPlanSP plan_sp = GetDebugFrameAugmentedUnwindPlan(target, thread))
return plan_sp;
+ if (UnwindPlanSP plan_sp = GetSymbolFileUnwindPlan(thread))
+ return plan_sp;
return assembly_sp;
}
Index: source/Plugins/Process/Utility/RegisterContextLLDB.cpp
===================================================================
--- source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -244,8 +244,8 @@
}
if (func_unwinders_sp.get() != nullptr)
- call_site_unwind_plan =
- func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget());
+ call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(
+ process->GetTarget(), m_thread);
if (call_site_unwind_plan.get() != nullptr) {
m_fallback_unwind_plan_sp = call_site_unwind_plan;
@@ -873,7 +873,8 @@
// location what helps in the most common cases when the instruction
// emulation fails.
UnwindPlanSP call_site_unwind_plan =
- func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget());
+ func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(),
+ m_thread);
if (call_site_unwind_plan &&
call_site_unwind_plan.get() != unwind_plan_sp.get() &&
call_site_unwind_plan->GetSourceName() !=
@@ -909,8 +910,8 @@
// Typically this is unwind info from an eh_frame section intended for
// exception handling; only valid at call sites
if (process) {
- unwind_plan_sp =
- func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget());
+ unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite(
+ process->GetTarget(), m_thread);
}
int valid_offset = -1;
if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) {
@@ -940,7 +941,8 @@
// 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 =
- func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget());
+ func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(),
+ m_thread);
if (call_site_unwind_plan &&
call_site_unwind_plan.get() != unwind_plan_sp.get() &&
call_site_unwind_plan->GetSourceName() !=
Index: source/Commands/CommandObjectTarget.cpp
===================================================================
--- source/Commands/CommandObjectTarget.cpp
+++ source/Commands/CommandObjectTarget.cpp
@@ -3521,7 +3521,7 @@
non_callsite_unwind_plan->GetSourceName().AsCString());
}
UnwindPlanSP callsite_unwind_plan =
- func_unwinders_sp->GetUnwindPlanAtCallSite(*target);
+ func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread);
if (callsite_unwind_plan) {
result.GetOutputStream().Printf(
"Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
Index: lit/SymbolFile/Breakpad/unwind-via-stack-cfi.test
===================================================================
--- /dev/null
+++ lit/SymbolFile/Breakpad/unwind-via-stack-cfi.test
@@ -0,0 +1,21 @@
+# RUN: %lldb -c %S/Inputs/unwind-via-stack-cfi.dmp \
+# RUN: -o "target symbols add %S/Inputs/unwind-via-stack-cfi.syms" -s %s -b\
+# RUN: | FileCheck %s
+
+image show-unwind -n bar
+# CHECK-LABEL: image show-unwind -n bar
+# CHECK: Asynchronous (not restricted to call-sites) UnwindPlan is 'breakpad STACK CFI'
+# CHECK: Synchronous (restricted to call-sites) UnwindPlan is 'breakpad STACK CFI'
+# CHECK: Symbol file UnwindPlan:
+# CHECK-NEXT: This UnwindPlan originally sourced from breakpad STACK CFI
+# CHECK-NEXT: This UnwindPlan is sourced from the compiler: yes.
+# CHECK-NEXT: This UnwindPlan is valid at all instruction locations: no.
+# CHECK-NEXT: Address range of this UnwindPlan: [linux-x86_64_not_crashed..module_image + 1056-0x0000000000000449)
+# CHECK-NEXT: row[0]: 0: CFA=DW_OP_breg6 +0, DW_OP_deref => rbp=DW_OP_pick 0x00, DW_OP_deref rsp=DW_OP_pick 0x00, DW_OP_consts +16, DW_OP_plus rip=DW_OP_pick 0x00, DW_OP_consts +8, DW_OP_plus , DW_OP_deref
+
+thread backtrace
+# CHECK-LABEL: thread backtrace
+# CHECK: frame #0: 0x00007f6b5a9ebfc3 libbreakpad.so
+# CHECK: frame #1: 0x0000000000400430 linux-x86_64_not_crashed`bar + 16
+# CHECK: frame #2: 0x0000000000400497 linux-x86_64_not_crashed`_start + 23
+# CHECK-NOT: frame
Index: lit/SymbolFile/Breakpad/stack-cfi-parsing.test
===================================================================
--- lit/SymbolFile/Breakpad/stack-cfi-parsing.test
+++ lit/SymbolFile/Breakpad/stack-cfi-parsing.test
@@ -4,6 +4,8 @@
image show-unwind -n func0
# CHECK-LABEL: image show-unwind -n func0
+# CHECK: Asynchronous (not restricted to call-sites) UnwindPlan is 'breakpad STACK CFI'
+# CHECK: Synchronous (restricted to call-sites) UnwindPlan is 'breakpad STACK CFI'
# CHECK: Symbol file UnwindPlan:
# CHECK-NEXT: This UnwindPlan originally sourced from breakpad STACK CFI
# CHECK-NEXT: This UnwindPlan is sourced from the compiler: yes.
@@ -42,6 +44,8 @@
# Finally, try an unwind plan with just a single row
image show-unwind -n func9
# CHECK-LABEL: image show-unwind -n func9
+# CHECK: Asynchronous (not restricted to call-sites) UnwindPlan is 'breakpad STACK CFI'
+# CHECK: Synchronous (restricted to call-sites) UnwindPlan is 'breakpad STACK CFI'
# CHECK: Symbol file UnwindPlan:
# CHECK: Address range of this UnwindPlan: [stack-cfi-parsing.out..module_image + 9-0x000000000000000a)
# CHECK: row[0]: 0: CFA=DW_OP_breg6 +0 => rip=DW_OP_breg0 +0
Index: lit/SymbolFile/Breakpad/Inputs/unwind-via-stack-cfi.syms
===================================================================
--- /dev/null
+++ lit/SymbolFile/Breakpad/Inputs/unwind-via-stack-cfi.syms
@@ -0,0 +1,6 @@
+MODULE Linux x86_64 603FCF6CA7FF4BCC86AE8FF44DB2576A0 linux-x86_64_not_crashed
+INFO CODE_ID 6CCF3F60FFA7CC4B86AE8FF44DB2576A68983611
+PUBLIC 420 0 bar
+PUBLIC 450 0 foo
+PUBLIC 480 0 _start
+STACK CFI INIT 420 29 .cfa: $rbp ^ .ra: .cfa 8 + ^ $rsp: .cfa 16 + $rbp: .cfa ^
Index: include/lldb/Symbol/FuncUnwinders.h
===================================================================
--- include/lldb/Symbol/FuncUnwinders.h
+++ include/lldb/Symbol/FuncUnwinders.h
@@ -35,7 +35,7 @@
~FuncUnwinders();
- lldb::UnwindPlanSP GetUnwindPlanAtCallSite(Target &target);
+ lldb::UnwindPlanSP GetUnwindPlanAtCallSite(Target &target, Thread &thread);
lldb::UnwindPlanSP GetUnwindPlanAtNonCallSite(Target &target,
lldb_private::Thread &thread);
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits