[Lldb-commits] [lldb] r139760 - in /lldb/trunk: include/lldb/Symbol/FuncUnwinders.h source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp source/Plugins/Process/Utility/RegisterContextLLDB.cpp source/Symbol/FuncUnwinders.cpp

Jason Molenda jmolenda at apple.com
Wed Sep 14 17:44:34 PDT 2011


Author: jmolenda
Date: Wed Sep 14 19:44:34 2011
New Revision: 139760

URL: http://llvm.org/viewvc/llvm-project?rev=139760&view=rev
Log:

Have the FuncUnwinder object request & provide an architecture-defined
UnwindPlan for unwinding from the first instruction of an otherwise
unknown function call (GetUnwindPlanArchitectureDefaultAtFunctionEntry()).

Update RegisterContextLLDB::GetFullUnwindPlanForFrame() to detect the
case of a frame 0 at address 0x0 which indicates that we jumped through
a NULL function pointer.  Use the ABI's FunctionEntryUnwindPlan to
find the caller frame.

These changes make it so lldb can identify the calling frame correctly
in code like

int main ()
{
  void (*f)(void) = 0;
  f();
}



Modified:
    lldb/trunk/include/lldb/Symbol/FuncUnwinders.h
    lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
    lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
    lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
    lldb/trunk/source/Symbol/FuncUnwinders.cpp

Modified: lldb/trunk/include/lldb/Symbol/FuncUnwinders.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/FuncUnwinders.h?rev=139760&r1=139759&r2=139760&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/FuncUnwinders.h (original)
+++ lldb/trunk/include/lldb/Symbol/FuncUnwinders.h Wed Sep 14 19:44:34 2011
@@ -55,6 +55,9 @@
     lldb::UnwindPlanSP
     GetUnwindPlanArchitectureDefault (lldb_private::Thread& thread);
 
+    lldb::UnwindPlanSP
+    GetUnwindPlanArchitectureDefaultAtFunctionEntry (lldb_private::Thread& thread);
+
     Address&
     GetFirstNonPrologueInsn (Target& target);
 
@@ -78,11 +81,14 @@
     lldb::UnwindPlanSP m_unwind_plan_non_call_site_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;
 
     bool m_tried_unwind_at_call_site:1,
          m_tried_unwind_at_non_call_site:1,
          m_tried_unwind_fast:1,
-         m_tried_unwind_arch_default:1;
+         m_tried_unwind_arch_default:1,
+         m_tried_unwind_arch_default_at_func_entry:1;
+         
          
     Address m_first_non_prologue_insn;
 

Modified: lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp?rev=139760&r1=139759&r2=139760&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp Wed Sep 14 19:44:34 2011
@@ -538,7 +538,7 @@
     
     // All other registers are the same.
     
-    unwind_plan.SetSourceName (pluginName);
+    unwind_plan.SetSourceName ("arm at-func-entry default");
     return true;
 }
 

Modified: lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp?rev=139760&r1=139759&r2=139760&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp Wed Sep 14 19:44:34 2011
@@ -803,7 +803,7 @@
     row.SetCFAOffset (4);
     row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);    
     unwind_plan.AppendRow (row);
-    unwind_plan.SetSourceName (pluginName);
+    unwind_plan.SetSourceName ("i386 at-func-entry default");
     return true;
 }
 

Modified: lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp?rev=139760&r1=139759&r2=139760&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp Wed Sep 14 19:44:34 2011
@@ -661,7 +661,7 @@
     row.SetCFAOffset (8);
     row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);    
     unwind_plan.AppendRow (row);
-    unwind_plan.SetSourceName (pluginName);
+    unwind_plan.SetSourceName ("x86_64 at-func-entry default");
     return true;
 }
 

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp?rev=139760&r1=139759&r2=139760&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Wed Sep 14 19:44:34 2011
@@ -552,7 +552,19 @@
         m_all_registers_available = true;
     }
 
-    // No Module for the current pc, try using the architecture default unwind.
+    // If we've done a jmp 0x0 / bl 0x0 (called through a null function pointer) so the pc is 0x0
+    // in the zeroth frame, we need to use the "unwind at first instruction" arch default UnwindPlan
+    if (behaves_like_zeroth_frame 
+        && m_current_pc.IsValid() 
+        && m_current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()) == 0)
+    {
+        unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
+        abi->CreateFunctionEntryUnwindPlan(*unwind_plan_sp);
+        m_frame_type = eNormalFrame;
+        return unwind_plan_sp;
+    }
+
+    // No Module fm_current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()or the current pc, try using the architecture default unwind.
     if (!m_current_pc.IsValid() || m_current_pc.GetModule() == NULL || m_current_pc.GetModule()->GetObjectFile() == NULL)
     {
         m_frame_type = eNormalFrame;

Modified: lldb/trunk/source/Symbol/FuncUnwinders.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/FuncUnwinders.cpp?rev=139760&r1=139759&r2=139760&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/FuncUnwinders.cpp (original)
+++ lldb/trunk/source/Symbol/FuncUnwinders.cpp Wed Sep 14 19:44:34 2011
@@ -42,6 +42,7 @@
     m_tried_unwind_at_non_call_site (false),
     m_tried_unwind_fast (false),
     m_tried_unwind_arch_default (false),
+    m_tried_unwind_arch_default_at_func_entry (false),
     m_first_non_prologue_insn() 
 {
 }
@@ -181,6 +182,43 @@
     return m_unwind_plan_arch_default_sp;
 }
 
+UnwindPlanSP
+FuncUnwinders::GetUnwindPlanArchitectureDefaultAtFunctionEntry (Thread& thread)
+{
+    // Lock the mutex to ensure we can always give out the most appropriate
+    // information. We want to make sure if someone requests an unwind
+    // plan, that they get one and don't run into a race condition where one
+    // thread has started to create the unwind plan and has put it into 
+    // the auto_ptr member variable, and have another thread enter this function
+    // and return the partially filled pointer contained in the auto_ptr.
+    // We also want to make sure that we lock out other unwind plans from
+    // being accessed until this one is done creating itself in case someone
+    // had some code like:
+    //  UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...)
+    //  if (best_unwind_plan == NULL)
+    //      best_unwind_plan = GetUnwindPlanAtNonCallSite (...)
+    Mutex::Locker locker (m_mutex);
+    if (m_tried_unwind_arch_default_at_func_entry == false && m_unwind_plan_arch_default_at_func_entry_sp.get() == NULL)
+    {
+        m_tried_unwind_arch_default_at_func_entry = true;
+        Address current_pc;
+        Target *target = thread.CalculateTarget();
+        if (target)
+        {
+            ABI *abi = thread.GetProcess().GetABI().get();
+            if (abi)
+            {
+                m_unwind_plan_arch_default_at_func_entry_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
+                if (m_unwind_plan_arch_default_at_func_entry_sp)
+                    abi->CreateFunctionEntryUnwindPlan(*m_unwind_plan_arch_default_at_func_entry_sp);
+            }
+        }
+    }
+
+    return m_unwind_plan_arch_default_sp;
+}
+
+
 Address&
 FuncUnwinders::GetFirstNonPrologueInsn (Target& target)
 {





More information about the lldb-commits mailing list