[Lldb-commits] [lldb] r147747 - in /lldb/trunk: include/lldb/Target/ABI.h source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h source/Plugins/Process/Utility/RegisterContextLLDB.cpp

Greg Clayton gclayton at apple.com
Sat Jan 7 21:54:36 PST 2012


Author: gclayton
Date: Sat Jan  7 23:54:35 2012
New Revision: 147747

URL: http://llvm.org/viewvc/llvm-project?rev=147747&view=rev
Log:
<rdar://problem/10645694> 

Fixed an ARM backtracing issue where if the previous frame was a thumb
function and it was a tail call so that the current frame returned to
an address that would fall into the next function, we would use the
next function as the basis for how we unwound the previous frame's
registers and of course get things wrong. We now fix the PC code
address using the current ABI plug-in, and the ARM ABI plug-in has
been modified to correctly fix the code address. So when we do the
symbol context lookup, instead of taking an address like 0x1001 and
decrementing 1, and looking up the symbol context for a frame, we
now correctly fix 0x1001 to 0x1000, then decrement that by 1 to
get the correct symbol context.

I added a bunch more logging to "log enable lldb uwnind" to help
us in the future. We now log the PC, FP and SP (if they are available),
and we also dump the "active_row" that we find for unwinding a frame.


Modified:
    lldb/trunk/include/lldb/Target/ABI.h
    lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp

Modified: lldb/trunk/include/lldb/Target/ABI.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ABI.h?rev=147747&r1=147746&r2=147747&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ABI.h (original)
+++ lldb/trunk/include/lldb/Target/ABI.h Sat Jan  7 23:54:35 2012
@@ -76,6 +76,15 @@
     virtual bool
     CodeAddressIsValid (lldb::addr_t pc) = 0;    
 
+    virtual bool
+    FixCodeAddress (lldb::addr_t pc)
+    {
+        // Some targets might use bits in a code address to indicate
+        // a mode switch. ARM uses bit zero to signify a code address is
+        // thumb, so any ARM ABI plug-ins would strip those bits.
+        return pc;
+    }
+
     virtual const RegisterInfo *
     GetRegisterInfoArray (uint32_t &count) = 0;
 

Modified: lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h?rev=147747&r1=147746&r2=147747&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h (original)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h Sat Jan  7 23:54:35 2012
@@ -82,6 +82,14 @@
         return pc <= UINT32_MAX;
     }
     
+    virtual bool
+    FixCodeAddress (lldb::addr_t pc)
+    {
+        // ARM uses bit zero to signify a code address is thumb, so we must
+        // strip bit zero in any code addresses.
+        return pc & ~(lldb::addr_t)1;
+    }
+
     virtual const lldb_private::RegisterInfo *
     GetRegisterInfoArray (uint32_t &count);
 

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=147747&r1=147746&r2=147747&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Sat Jan  7 23:54:35 2012
@@ -87,6 +87,8 @@
 {
     StackFrameSP frame_sp (m_thread.GetStackFrameAtIndex (0));
 
+    LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+
     if (m_thread.GetRegisterContext() == NULL)
     {
         m_frame_type = eNotAValidFrame;
@@ -149,6 +151,13 @@
     {
         active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
         row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
+        if (active_row && log)
+        {
+            StreamString active_row_strm;
+            active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(&m_thread.GetProcess().GetTarget()));
+            log->Printf("%*sFrame %u active row: %s",
+                        m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, active_row_strm.GetString().c_str());
+        }
     }
 
     if (active_row == NULL)
@@ -157,6 +166,7 @@
         return;
     }
 
+    
     addr_t cfa_regval;
     if (!ReadGPRValue (row_register_kind, active_row->GetCFARegister(), cfa_regval))
     {
@@ -170,7 +180,13 @@
 
     m_cfa = cfa_regval + cfa_offset;
 
-    LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+    if (log)
+    {
+        log->Printf("%*sFrame %u cfa_regval = 0x%16.16llx (cfa_regval = 0x%16.16llx, cfa_offset = %i)",
+                    m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+                    m_cfa, cfa_regval, cfa_offset);
+    }
+    
 
     // A couple of sanity checks..
     if (cfa_regval == LLDB_INVALID_ADDRESS || cfa_regval == 0 || cfa_regval == 1)
@@ -232,6 +248,20 @@
         m_frame_type = eNotAValidFrame;
         return;
     }
+    
+    if (log)
+    {
+        log->Printf("%*sFrame %u pc = 0x%16.16llx",
+                    m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, pc);
+        addr_t reg_val;
+        if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val))
+            log->Printf("%*sFrame %u fp = 0x%16.16llx",
+                        m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, reg_val);
+
+        if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val))
+            log->Printf("%*sFrame %u sp = 0x%16.16llx",
+                        m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, reg_val);
+    }
 
     // A pc of 0x0 means it's the end of the stack crawl
     if (pc == 0)
@@ -239,6 +269,12 @@
         m_frame_type = eNotAValidFrame;
         return;
     }
+    
+    // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
+    // this will strip bit zero in case we read a PC from memory or from the LR.   
+    ABI *abi = m_thread.GetProcess().GetABI().get();
+    if (abi)
+        pc = abi->FixCodeAddress(pc);
 
     // Test the pc value to see if we know it's in an unmapped/non-executable region of memory.
     uint32_t permissions;
@@ -277,7 +313,6 @@
             log->Printf("%*sFrame %u using architectural default unwind method",
                         m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number);
         }
-        ABI *abi = m_thread.GetProcess().GetABI().get();
         if (abi)
         {
             m_fast_unwind_plan_sp.reset ();
@@ -452,6 +487,13 @@
     {
         active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
         row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind ();
+        if (active_row && log)
+        {
+            StreamString active_row_strm;
+            active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(&m_thread.GetProcess().GetTarget()));
+            log->Printf("%*sFrame %u active row: %s",
+                        m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, active_row_strm.GetString().c_str());
+        }
     }
     else 
     {
@@ -460,6 +502,13 @@
         {
             active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
             row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
+            if (active_row && log)
+            {
+                StreamString active_row_strm;
+                active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(&m_thread.GetProcess().GetTarget()));
+                log->Printf("%*sFrame %u active row: %s",
+                            m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, active_row_strm.GetString().c_str());
+            }
         }
     }
 
@@ -485,6 +534,13 @@
 
     m_cfa = cfa_regval + cfa_offset;
 
+    if (log)
+    {
+        log->Printf("%*sFrame %u cfa_regval = 0x%16.16llx (cfa_regval = 0x%16.16llx, cfa_offset = %i)",
+                    m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+                    m_cfa, cfa_regval, cfa_offset);
+    }
+
     // A couple of sanity checks..
     if (cfa_regval == LLDB_INVALID_ADDRESS || cfa_regval == 0 || cfa_regval == 1)
     { 





More information about the lldb-commits mailing list