diff options
author | Todd Fiala <todd.fiala@gmail.com> | 2014-08-25 20:29:09 +0000 |
---|---|---|
committer | Todd Fiala <todd.fiala@gmail.com> | 2014-08-25 20:29:09 +0000 |
commit | 0562524b457d218152810f72a181d543fe348933 (patch) | |
tree | de68ad094f021b8d3409b1feb5bc331e62e88ec7 /lldb/source/Symbol/FuncUnwinders.cpp | |
parent | be7bf7285be142f0886b440bb3b4f3a27fcc3c2f (diff) | |
download | bcm5719-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.cpp | 15 |
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(); |