diff options
Diffstat (limited to 'lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp')
-rw-r--r-- | lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp | 187 |
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; |