summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp')
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp187
1 files changed, 108 insertions, 79 deletions
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
index 5847718d4e2..38f2c46f8e8 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -31,97 +31,120 @@ UnwindLLDB::UnwindLLDB (Thread &thread) :
uint32_t
UnwindLLDB::GetFrameCount()
{
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
if (m_frames.empty())
{
- // First, set up the 0th (initial) frame
- CursorSP first_cursor_sp(new Cursor ());
- RegisterContextSP no_frame; // an empty shared pointer
- RegisterContextLLDB *first_register_ctx = new RegisterContextLLDB(m_thread, no_frame, first_cursor_sp->sctx, 0);
- if (!first_register_ctx->IsValid())
- {
- delete first_register_ctx;
+ if (!AddFirstFrame ())
return 0;
+ while (AddOneMoreFrame ())
+ ;
+ }
+ return m_frames.size ();
+}
+
+bool
+UnwindLLDB::AddFirstFrame ()
+{
+ // First, set up the 0th (initial) frame
+ CursorSP first_cursor_sp(new Cursor ());
+ RegisterContextSP no_frame;
+ RegisterContextLLDB *first_register_ctx = new RegisterContextLLDB(m_thread, no_frame, first_cursor_sp->sctx, 0);
+ if (!first_register_ctx->IsValid())
+ {
+ delete first_register_ctx;
+ return false;
+ }
+ if (!first_register_ctx->GetCFA (first_cursor_sp->cfa))
+ {
+ delete first_register_ctx;
+ return false;
+ }
+ if (!first_register_ctx->GetPC (first_cursor_sp->start_pc))
+ {
+ delete first_register_ctx;
+ return false;
+ }
+ // Reuse the StackFrame provided by the processor native machine context for the first frame
+ first_register_ctx->SetStackFrame (m_thread.GetStackFrameAtIndex(0).get());
+ RegisterContextSP first_register_ctx_sp(first_register_ctx);
+ first_cursor_sp->reg_ctx = first_register_ctx_sp;
+ m_frames.push_back (first_cursor_sp);
+ return true;
+}
+
+// For adding a non-zero stack frame to m_frames.
+bool
+UnwindLLDB::AddOneMoreFrame ()
+{
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ CursorSP cursor_sp(new Cursor ());
+ RegisterContextLLDB *register_ctx;
+
+ // Frame zero is a little different
+ if (m_frames.size() == 0)
+ return false;
+
+ uint32_t cur_idx = m_frames.size ();
+ register_ctx = new RegisterContextLLDB (m_thread, m_frames[cur_idx - 1]->reg_ctx, cursor_sp->sctx, cur_idx);
+
+ if (!register_ctx->IsValid())
+ {
+ delete register_ctx;
+ if (log)
+ {
+ log->Printf("%*sFrame %d invalid RegisterContext for this frame, stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
}
- if (!first_register_ctx->GetCFA (first_cursor_sp->cfa))
+ return false;
+ }
+ if (!register_ctx->GetCFA (cursor_sp->cfa))
+ {
+ delete register_ctx;
+ if (log)
{
- delete first_register_ctx;
- return 0;
+ log->Printf("%*sFrame %d did not get CFA for this frame, stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
}
- if (!first_register_ctx->GetPC (first_cursor_sp->start_pc))
+ return false;
+ }
+ if (cursor_sp->cfa == (addr_t) -1 || cursor_sp->cfa == 1 || cursor_sp->cfa == 0)
+ {
+ delete register_ctx;
+ if (log)
{
- delete first_register_ctx;
- return 0;
+ log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
}
- // Reuse the StackFrame provided by the processor native machine context for the first frame
- first_register_ctx->SetStackFrame (m_thread.GetStackFrameAtIndex(0).get());
- RegisterContextSP first_register_ctx_sp(first_register_ctx);
- first_cursor_sp->reg_ctx = first_register_ctx_sp;
- m_frames.push_back (first_cursor_sp);
-
- // Now walk up the rest of the stack
- while (1)
+ return false;
+ }
+ if (!register_ctx->GetPC (cursor_sp->start_pc))
+ {
+ delete register_ctx;
+ if (log)
{
- CursorSP cursor_sp(new Cursor ());
- RegisterContextLLDB *register_ctx;
- uint32_t cur_idx = m_frames.size ();
- register_ctx = new RegisterContextLLDB (m_thread, m_frames[cur_idx - 1]->reg_ctx, cursor_sp->sctx, cur_idx);
- if (!register_ctx->IsValid())
- {
- delete register_ctx;
- if (log)
- {
- log->Printf("%*sFrame %d invalid RegisterContext for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
- }
- break;
- }
- if (!register_ctx->GetCFA (cursor_sp->cfa))
- {
- delete register_ctx;
- if (log)
- {
- log->Printf("%*sFrame %d did not get CFA for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
- }
- break;
- }
- if (cursor_sp->cfa == (addr_t) -1 || cursor_sp->cfa == 1 || cursor_sp->cfa == 0)
- {
- delete register_ctx;
- if (log)
- {
- log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
- }
- break;
- }
- if (!register_ctx->GetPC (cursor_sp->start_pc))
- {
- delete register_ctx;
- if (log)
- {
- log->Printf("%*sFrame %d did not get PC for this frame, stopping stack walk",
- cur_idx < 100 ? cur_idx : 100, "", cur_idx);
- }
- break;
- }
- RegisterContextSP register_ctx_sp(register_ctx);
- StackFrame *frame = new StackFrame(cur_idx, cur_idx, m_thread, register_ctx_sp, cursor_sp->cfa, cursor_sp->start_pc, &(cursor_sp->sctx));
- register_ctx->SetStackFrame (frame);
- cursor_sp->reg_ctx = register_ctx_sp;
- m_frames.push_back (cursor_sp);
+ log->Printf("%*sFrame %d did not get PC for this frame, stopping stack walk",
+ cur_idx < 100 ? cur_idx : 100, "", cur_idx);
}
+ return false;
}
- return m_frames.size ();
+ RegisterContextSP register_ctx_sp(register_ctx);
+ StackFrame *frame = new StackFrame(cur_idx, cur_idx, m_thread, register_ctx_sp, cursor_sp->cfa, cursor_sp->start_pc, &(cursor_sp->sctx));
+ register_ctx->SetStackFrame (frame);
+ cursor_sp->reg_ctx = register_ctx_sp;
+ m_frames.push_back (cursor_sp);
+ return true;
}
bool
UnwindLLDB::GetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc)
{
- // FIXME don't get the entire stack if it isn't needed.
if (m_frames.size() == 0)
- GetFrameCount();
+ {
+ if (!AddFirstFrame())
+ return false;
+ }
+
+ while (idx >= m_frames.size() && AddOneMoreFrame ())
+ ;
if (idx < m_frames.size ())
{
@@ -136,15 +159,21 @@ RegisterContext *
UnwindLLDB::CreateRegisterContextForFrame (StackFrame *frame)
{
uint32_t idx = frame->GetFrameIndex ();
-
- // FIXME don't get the entire stack if it isn't needed.
- if (m_frames.size() == 0)
- GetFrameCount();
-
+
if (idx == 0)
{
return m_thread.GetRegisterContext();
}
+
+ if (m_frames.size() == 0)
+ {
+ if (!AddFirstFrame())
+ return NULL;
+ }
+
+ while (idx >= m_frames.size() && AddOneMoreFrame ())
+ ;
+
if (idx < m_frames.size ())
return m_frames[idx]->reg_ctx.get();
return NULL;
OpenPOWER on IntegriCloud