forked from OSchip/llvm-project
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. llvm-svn: 142331
This commit is contained in:
parent
f333f8c40d
commit
e858e33200
|
@ -448,6 +448,38 @@ RegisterContextLLDB::InitializeNonZerothFrame()
|
|||
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 @@ RegisterContextLLDB::GetCFA (addr_t& cfa)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
RegisterContextLLDB::SharedPtr
|
||||
RegisterContextLLDB::GetNextFrame ()
|
||||
{
|
||||
return m_next_frame;
|
||||
}
|
||||
|
||||
// Retrieve the address of the start of the function of THIS frame
|
||||
|
||||
bool
|
||||
|
|
|
@ -122,6 +122,9 @@ private:
|
|||
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.
|
||||
|
|
Loading…
Reference in New Issue