[Lldb-commits] [lldb] r142331 - in /lldb/trunk/source/Plugins/Process/Utility: RegisterContextLLDB.cpp RegisterContextLLDB.h

Jason Molenda jmolenda at apple.com
Mon Oct 17 19:57:27 PDT 2011


Author: jmolenda
Date: Mon Oct 17 21:57:27 2011
New Revision: 142331

URL: http://llvm.org/viewvc/llvm-project?rev=142331&view=rev
Log:
Add code to RegisterContextLLDB::InitializeNonZerothFrame to detect a multiple stack frames 
with the same CFA (or an alternating sequence between two CFA values) to catch a handful of
unwind cases where lldb will inf loop trying to unwind a stack.

Modified:
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h

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=142331&r1=142330&r2=142331&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Mon Oct 17 21:57:27 2011
@@ -448,6 +448,38 @@
         return;
     }
 
+    // If we have a bad stack setup, we can get the same CFA value multiple times -- or even
+    // more devious, we can actually oscillate between two CFA values.  Detect that here and
+    // break out to avoid a possible infinite loop in lldb trying to unwind the stack.
+    addr_t next_frame_cfa;
+    addr_t next_next_frame_cfa = LLDB_INVALID_ADDRESS;
+    if (m_next_frame.get() && m_next_frame->GetCFA(next_frame_cfa))
+    {
+        bool repeating_frames = false;
+        if (next_frame_cfa == m_cfa)
+        {
+            repeating_frames = true;
+        }
+        else
+        {
+            if (m_next_frame->GetNextFrame() && m_next_frame->GetNextFrame()->GetCFA(next_next_frame_cfa)
+                && next_next_frame_cfa == m_cfa)
+            {
+                repeating_frames = true;
+            }
+        }
+        if (repeating_frames)
+        {
+            if (log)
+            {
+                log->Printf("%*sFrame %u same CFA address as next frame, assuming the unwind is looping - stopping",
+                            m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number);
+            }
+            m_frame_type = eNotAValidFrame;
+            return;
+        }
+    }
+
     if (log)
     {
         log->Printf("%*sFrame %u initialized frame current pc is 0x%llx cfa is 0x%llx", 
@@ -1219,6 +1251,13 @@
     return true;
 }
 
+
+RegisterContextLLDB::SharedPtr
+RegisterContextLLDB::GetNextFrame ()
+{
+    return m_next_frame;
+}
+
 // Retrieve the address of the start of the function of THIS frame
 
 bool

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h?rev=142331&r1=142330&r2=142331&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h Mon Oct 17 21:57:27 2011
@@ -122,6 +122,9 @@
     void 
     InitializeNonZerothFrame();
 
+    SharedPtr
+    GetNextFrame ();
+
     // Provide a location for where THIS function saved the CALLER's register value
     // Or a frame "below" this one saved it, i.e. a function called by this one, preserved a register that this
     // function didn't modify/use.





More information about the lldb-commits mailing list