[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