ABI plug-ins must implement the following pure virtual functions:
virtual bool
ABI::StackUsesFrames () = 0;
Should return true if your ABI uses frames when doing stack backtraces. This
means a frame pointer is used that points to the previous stack frame in some
way or another.
virtual bool
ABI::CallFrameAddressIsValid (lldb::addr_t cfa) = 0;
Should take a look at a call frame address (CFA) which is just the stack
pointer value upon entry to a function. ABIs usually impose alignment
restrictions (4, 8 or 16 byte aligned), and zero is usually not allowed.
This function should return true if "cfa" is valid call frame address for
the ABI, and false otherwise. This is used by the generic stack frame unwinding
code to help determine when a stack ends.
virtual bool
ABI::CodeAddressIsValid (lldb::addr_t pc) = 0;
Validates a possible PC value and returns true if an opcode can be at "pc".
Some ABIs or architectures have fixed width instructions and must be aligned
to a 2 or 4 byte boundary. "pc" can be an opcode or a callable address which
means the load address might be decorated with extra bits (such as bit zero
to indicate a thumb function call for ARM targets), so take this into account
when returning true or false. The address should also be validated to ensure
it is a valid address for the address size of the inferior process. 32 bit
targets should make sure the address is less than UINT32_MAX.
Modified UnwindLLDB to use the new ABI functions to help it properly terminate
stacks.
Modified the mach-o function that extracts dependent files to not resolve the
path as the paths inside a binary might not match those on the current
host system.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@132021 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/Utility/UnwindLLDB.cpp b/source/Plugins/Process/Utility/UnwindLLDB.cpp
index 2de786f..565983d 100644
--- a/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -41,7 +41,10 @@
#endif
if (!AddFirstFrame ())
return 0;
- while (AddOneMoreFrame ())
+
+ ABI *abi = m_thread.GetProcess().GetABI().get();
+
+ while (AddOneMoreFrame (abi))
{
#if DEBUG_FRAME_SPEED
if ((m_frames.size() % FRAME_COUNT) == 0)
@@ -66,32 +69,32 @@
{
// First, set up the 0th (initial) frame
CursorSP first_cursor_sp(new Cursor ());
- std::auto_ptr<RegisterContextLLDB> first_register_ctx_ap (new RegisterContextLLDB (m_thread,
- RegisterContextLLDB::SharedPtr(),
- first_cursor_sp->sctx,
- 0));
- if (first_register_ctx_ap.get() == NULL)
+ RegisterContextLLDB::SharedPtr reg_ctx_sp (new RegisterContextLLDB (m_thread,
+ RegisterContextLLDB::SharedPtr(),
+ first_cursor_sp->sctx,
+ 0));
+ if (reg_ctx_sp.get() == NULL)
return false;
- if (!first_register_ctx_ap->IsValid())
+ if (!reg_ctx_sp->IsValid())
return false;
- if (!first_register_ctx_ap->GetCFA (first_cursor_sp->cfa))
+ if (!reg_ctx_sp->GetCFA (first_cursor_sp->cfa))
return false;
- if (!first_register_ctx_ap->ReadPC (first_cursor_sp->start_pc))
+ if (!reg_ctx_sp->ReadPC (first_cursor_sp->start_pc))
return false;
// Everything checks out, so release the auto pointer value and let the
// cursor own it in its shared pointer
- first_cursor_sp->reg_ctx.reset(first_register_ctx_ap.release());
+ first_cursor_sp->reg_ctx = reg_ctx_sp;
m_frames.push_back (first_cursor_sp);
return true;
}
// For adding a non-zero stack frame to m_frames.
bool
-UnwindLLDB::AddOneMoreFrame ()
+UnwindLLDB::AddOneMoreFrame (ABI *abi)
{
LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
CursorSP cursor_sp(new Cursor ());
@@ -101,14 +104,14 @@
return false;
uint32_t cur_idx = m_frames.size ();
- std::auto_ptr<RegisterContextLLDB> register_ctx_ap(new RegisterContextLLDB (m_thread,
- m_frames[cur_idx - 1]->reg_ctx,
- cursor_sp->sctx,
- cur_idx));
- if (register_ctx_ap.get() == NULL)
+ RegisterContextLLDB::SharedPtr reg_ctx_sp(new RegisterContextLLDB (m_thread,
+ m_frames[cur_idx - 1]->reg_ctx,
+ cursor_sp->sctx,
+ cur_idx));
+ if (reg_ctx_sp.get() == NULL)
return false;
- if (!register_ctx_ap->IsValid())
+ if (!reg_ctx_sp->IsValid())
{
if (log)
{
@@ -117,7 +120,7 @@
}
return false;
}
- if (!register_ctx_ap->GetCFA (cursor_sp->cfa))
+ if (!reg_ctx_sp->GetCFA (cursor_sp->cfa))
{
if (log)
{
@@ -126,7 +129,7 @@
}
return false;
}
- if (cursor_sp->cfa == (addr_t) -1 || cursor_sp->cfa == 1 || cursor_sp->cfa == 0)
+ if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa))
{
if (log)
{
@@ -135,7 +138,7 @@
}
return false;
}
- if (!register_ctx_ap->ReadPC (cursor_sp->start_pc))
+ if (!reg_ctx_sp->ReadPC (cursor_sp->start_pc))
{
if (log)
{
@@ -144,16 +147,28 @@
}
return false;
}
+ if (abi && !abi->CodeAddressIsValid (cursor_sp->start_pc))
+ {
+ if (log)
+ {
+ log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
+ }
+ return false;
+ }
if (!m_frames.empty())
{
- if ((m_frames.back()->start_pc == cursor_sp->start_pc) &&
- (m_frames.back()->cfa == cursor_sp->cfa))
+ if (m_frames.back()->start_pc == cursor_sp->start_pc)
{
- // Infinite loop where the current cursor is the same as the previous one...
- return false;
+ if (m_frames.back()->cfa == cursor_sp->cfa)
+ return false; // Infinite loop where the current cursor is the same as the previous one...
+ else if (abi->StackUsesFrames())
+ {
+ if (reg_ctx_sp->GetFP() == 0)
+ return false;
+ }
}
}
- RegisterContextLLDB::SharedPtr reg_ctx_sp(register_ctx_ap.release());
cursor_sp->reg_ctx = reg_ctx_sp;
m_frames.push_back (cursor_sp);
return true;
@@ -168,7 +183,9 @@
return false;
}
- while (idx >= m_frames.size() && AddOneMoreFrame ())
+ ABI *abi = m_thread.GetProcess().GetABI().get();
+
+ while (idx >= m_frames.size() && AddOneMoreFrame (abi))
;
if (idx < m_frames.size ())
@@ -197,7 +214,9 @@
return reg_ctx_sp;
}
- while (idx >= m_frames.size() && AddOneMoreFrame ())
+ ABI *abi = m_thread.GetProcess().GetABI().get();
+
+ while (idx >= m_frames.size() && AddOneMoreFrame (abi))
;
if (idx < m_frames.size ())
diff --git a/source/Plugins/Process/Utility/UnwindLLDB.h b/source/Plugins/Process/Utility/UnwindLLDB.h
index 97b0882..9625e2e 100644
--- a/source/Plugins/Process/Utility/UnwindLLDB.h
+++ b/source/Plugins/Process/Utility/UnwindLLDB.h
@@ -63,7 +63,7 @@
typedef lldb::SharedPtr<Cursor>::Type CursorSP;
std::vector<CursorSP> m_frames;
- bool AddOneMoreFrame ();
+ bool AddOneMoreFrame (ABI *abi);
bool AddFirstFrame ();
//------------------------------------------------------------------