summaryrefslogtreecommitdiffstats
path: root/lldb/source/Symbol/FuncUnwinders.cpp
diff options
context:
space:
mode:
authorTodd Fiala <todd.fiala@gmail.com>2014-08-25 20:29:09 +0000
committerTodd Fiala <todd.fiala@gmail.com>2014-08-25 20:29:09 +0000
commit0562524b457d218152810f72a181d543fe348933 (patch)
treede68ad094f021b8d3409b1feb5bc331e62e88ec7 /lldb/source/Symbol/FuncUnwinders.cpp
parentbe7bf7285be142f0886b440bb3b4f3a27fcc3c2f (diff)
downloadbcm5719-llvm-0562524b457d218152810f72a181d543fe348933.tar.gz
bcm5719-llvm-0562524b457d218152810f72a181d543fe348933.zip
On x86 & x86_64, try to use eh_frame for frame 0.
We decided to use assmbly profiler instead of eh_frame for frame 0 because for compiler generated code, eh_frame is usually synchronous(a.k.a. only valid at call site); and we have no way to tell if it's asynchronous or not. But for x86 & x86_64 compiler generated code: 1. clang & GCC describes all prologue instructions in eh_frame; 2. mid-function stack pointer altering instructions can be easily detected. So we can grab eh_frame, and use assembly profiler to augment it into asynchronous unwind table. This change also benefits hand-written assembly; eh_frame for hand-written assembly is often asynchronous,so we have a much better chance to successfully unwind through them. Change by Tong Shen. llvm-svn: 216406
Diffstat (limited to 'lldb/source/Symbol/FuncUnwinders.cpp')
-rw-r--r--lldb/source/Symbol/FuncUnwinders.cpp15
1 files changed, 13 insertions, 2 deletions
diff --git a/lldb/source/Symbol/FuncUnwinders.cpp b/lldb/source/Symbol/FuncUnwinders.cpp
index 4ed04a00acc..d6f89bc299e 100644
--- a/lldb/source/Symbol/FuncUnwinders.cpp
+++ b/lldb/source/Symbol/FuncUnwinders.cpp
@@ -32,7 +32,7 @@ FuncUnwinders::FuncUnwinders
) :
m_unwind_table(unwind_table),
m_range(range),
- m_mutex (Mutex::eMutexTypeNormal),
+ m_mutex (Mutex::eMutexTypeRecursive),
m_unwind_plan_call_site_sp (),
m_unwind_plan_non_call_site_sp (),
m_unwind_plan_fast_sp (),
@@ -94,7 +94,7 @@ FuncUnwinders::GetUnwindPlanAtCallSite (int current_offset)
}
UnwindPlanSP
-FuncUnwinders::GetUnwindPlanAtNonCallSite (Thread& thread)
+FuncUnwinders::GetUnwindPlanAtNonCallSite (Target& target, Thread& thread, int current_offset)
{
// Lock the mutex to ensure we can always give out the most appropriate
// information. We want to make sure if someone requests an unwind
@@ -114,6 +114,17 @@ FuncUnwinders::GetUnwindPlanAtNonCallSite (Thread& thread)
UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler());
if (assembly_profiler_sp)
{
+ if (target.GetArchitecture().GetCore() == ArchSpec::eCore_x86_32_i386
+ || target.GetArchitecture().GetCore() == ArchSpec::eCore_x86_64_x86_64)
+ {
+ // For 0th frame on i386 & x86_64, we fetch eh_frame and try using assembly profiler
+ // to augment it into asynchronous unwind table.
+ GetUnwindPlanAtCallSite(current_offset);
+ if (m_unwind_plan_call_site_sp
+ && assembly_profiler_sp->AugmentUnwindPlanFromCallSite(m_range, thread, *m_unwind_plan_call_site_sp))
+ return m_unwind_plan_call_site_sp;
+ }
+
m_unwind_plan_non_call_site_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
if (!assembly_profiler_sp->GetNonCallSiteUnwindPlanFromAssembly (m_range, thread, *m_unwind_plan_non_call_site_sp))
m_unwind_plan_non_call_site_sp.reset();
OpenPOWER on IntegriCloud