diff options
| author | Jason Molenda <jmolenda@apple.com> | 2010-11-04 00:53:20 +0000 |
|---|---|---|
| committer | Jason Molenda <jmolenda@apple.com> | 2010-11-04 00:53:20 +0000 |
| commit | 5976200d43c802d07f76b16390b47e3454092e4e (patch) | |
| tree | 595ee15ff8f24f4b5c410c4095cd6abf4cc84ee1 /lldb/source/Plugins/Process | |
| parent | 743081d097f4470956de473cb194941a34e730a5 (diff) | |
| download | bcm5719-llvm-5976200d43c802d07f76b16390b47e3454092e4e.tar.gz bcm5719-llvm-5976200d43c802d07f76b16390b47e3454092e4e.zip | |
Handle the case where no eh_frame section is present.
RegisterContextLLDB holds a reference to the SymbolContext
in the vector of Cursors that UnwindLLDB maintains. Switch
UnwindLLDB to hold a vector of shared pointers of Cursors
so this reference doesn't become invalid.
Correctly falling back from the "fast" UnwindPlan to the
"full" UnwindPlan when additional registers need to be
retrieved.
llvm-svn: 118218
Diffstat (limited to 'lldb/source/Plugins/Process')
5 files changed, 81 insertions, 51 deletions
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp index d0b4eca8fdd..5b7ea7203ce 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -33,9 +33,13 @@ RegisterContextLLDB::RegisterContextLLDB (Thread& thread, int frame_number) : RegisterContext (thread), m_thread(thread), m_next_frame(next_frame), m_sym_ctx(sym_ctx), m_all_registers_available(false), m_registers(), - m_cfa (LLDB_INVALID_ADDRESS), m_start_pc (), m_current_pc (), m_frame_number (frame_number) + m_cfa (LLDB_INVALID_ADDRESS), m_start_pc (), m_current_pc (), m_frame_number (frame_number), + m_full_unwind_plan(NULL), m_fast_unwind_plan(NULL) { + m_sym_ctx.Clear(); + m_sym_ctx_valid = false; m_base_reg_ctx = m_thread.GetRegisterContext(); + if (IsFrameZero ()) { InitializeZerothFrame (); @@ -77,13 +81,11 @@ RegisterContextLLDB::InitializeZerothFrame() m_frame_type = eNotAValidFrame; return; } - m_sym_ctx = frame_sp->GetSymbolContext (eSymbolContextEverything); - const AddressRange *addr_range_ptr; - if (m_sym_ctx.function) - addr_range_ptr = &m_sym_ctx.function->GetAddressRange(); - else if (m_sym_ctx.symbol) - addr_range_ptr = m_sym_ctx.symbol->GetAddressRangePtr(); - + m_sym_ctx = frame_sp->GetSymbolContext (eSymbolContextFunction | eSymbolContextSymbol); + m_sym_ctx_valid = true; + AddressRange addr_range; + m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, addr_range); + m_current_pc = frame_sp->GetFrameCodeAddress(); static ConstString sigtramp_name ("_sigtramp"); @@ -98,11 +100,11 @@ RegisterContextLLDB::InitializeZerothFrame() m_frame_type = eNormalFrame; } - // If we were able to find a symbol/function, set addr_range_ptr to the bounds of that symbol/function. + // If we were able to find a symbol/function, set addr_range to the bounds of that symbol/function. // else treat the current pc value as the start_pc and record no offset. - if (addr_range_ptr) + if (addr_range.GetBaseAddress().IsValid()) { - m_start_pc = addr_range_ptr->GetBaseAddress(); + m_start_pc = addr_range.GetBaseAddress(); m_current_offset = frame_sp->GetFrameCodeAddress().GetOffset() - m_start_pc.GetOffset(); } else @@ -261,14 +263,17 @@ RegisterContextLLDB::InitializeNonZerothFrame() return; } - // set up our m_sym_ctx SymbolContext - m_current_pc.GetModule()->ResolveSymbolContextForAddress (m_current_pc, eSymbolContextFunction | eSymbolContextSymbol, m_sym_ctx); + // We require that eSymbolContextSymbol be successfully filled in or this context is of no use to us. + if ((m_current_pc.GetModule()->ResolveSymbolContextForAddress (m_current_pc, eSymbolContextFunction| eSymbolContextSymbol, m_sym_ctx) & eSymbolContextSymbol) == eSymbolContextSymbol) + { + m_sym_ctx_valid = true; + } - const AddressRange *addr_range_ptr; - if (m_sym_ctx.function) - addr_range_ptr = &m_sym_ctx.function->GetAddressRange(); - else if (m_sym_ctx.symbol) - addr_range_ptr = m_sym_ctx.symbol->GetAddressRangePtr(); + AddressRange addr_range; + if (!m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, addr_range)) + { + m_sym_ctx_valid = false; + } static ConstString sigtramp_name ("_sigtramp"); if ((m_sym_ctx.function && m_sym_ctx.function->GetMangled().GetMangledName() == sigtramp_name) @@ -284,9 +289,9 @@ RegisterContextLLDB::InitializeNonZerothFrame() // If we were able to find a symbol/function, set addr_range_ptr to the bounds of that symbol/function. // else treat the current pc value as the start_pc and record no offset. - if (addr_range_ptr) + if (addr_range.GetBaseAddress().IsValid()) { - m_start_pc = addr_range_ptr->GetBaseAddress(); + m_start_pc = addr_range.GetBaseAddress(); m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset(); } else @@ -458,6 +463,9 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame () { behaves_like_zeroth_frame = true; } + + // If this frame behaves like a 0th frame (currently executing or interrupted asynchronously), all registers + // can be retrieved. if (behaves_like_zeroth_frame) { m_all_registers_available = true; @@ -471,7 +479,10 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame () } FuncUnwindersSP fu; - fu = m_current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx); + if (m_sym_ctx_valid) + { + fu = m_current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx); + } // No FuncUnwinders available for this pc, try using architectural default unwind. if (fu.get() == NULL) @@ -718,9 +729,9 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc { if (log) { - log->Printf("%*sFrame %d could not supply caller's reg %d location", + log->Printf("%*sFrame %d could not convert lldb regnum %d into %d RegisterKind reg numbering scheme", m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum); + lldb_regnum, (int) unwindplan_registerkind); } return false; } @@ -735,9 +746,10 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc have_unwindplan_regloc = true; } } - else + + if (!have_unwindplan_regloc) { - // m_full_unwind_plan being NULL probably means that we haven't tried to find a full UnwindPlan yet + // m_full_unwind_plan being NULL means that we haven't tried to find a full UnwindPlan yet if (m_full_unwind_plan == NULL) { m_full_unwind_plan = GetFullUnwindPlanForFrame (); @@ -751,9 +763,9 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc { if (log) { - log->Printf("%*sFrame %d could not supply caller's reg %d location", + log->Printf("%*sFrame %d could not convert lldb regnum %d into %d RegisterKind reg numbering scheme", m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum); + lldb_regnum, (int) unwindplan_registerkind); } return false; } @@ -770,6 +782,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc } } } + if (have_unwindplan_regloc == false) { // If a volatile register is being requested, we don't want to forward m_next_frame's register contents diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h index d0611061221..9acad0f979d 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h @@ -163,14 +163,15 @@ private: // i.e. where THIS frame saved them /// - lldb_private::UnwindPlan *m_fast_unwind_plan; // may be NULL + lldb_private::UnwindPlan *m_fast_unwind_plan; // may be NULL lldb_private::UnwindPlan *m_full_unwind_plan; - bool m_all_registers_available; // Can we retrieve all regs or just nonvolatile regs? - int m_frame_type; // enum FrameType - int m_current_offset; // how far into the function we've executed; -1 if unknown + bool m_all_registers_available; // Can we retrieve all regs or just nonvolatile regs? + int m_frame_type; // enum FrameType + int m_current_offset; // how far into the function we've executed; -1 if unknown lldb_private::SymbolContext& m_sym_ctx; + bool m_sym_ctx_valid; // if ResolveSymbolContextForAddress fails, don't try to use m_sym_ctx - int m_frame_number; // What stack frame level this frame is - used for debug logging + int m_frame_number; // What stack frame level this frame is - used for debug logging lldb::addr_t m_cfa; lldb_private::Address m_start_pc; diff --git a/lldb/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp b/lldb/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp index 58b2ee0ac5c..e0f99d9255c 100644 --- a/lldb/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp +++ b/lldb/source/Plugins/Process/Utility/UnwindAssemblyProfiler-x86.cpp @@ -478,6 +478,10 @@ bool AssemblyParse_x86::instruction_length (Address addr, int &length) { const char *triple; + + if (!addr.IsValid()) + return false; + // FIXME should probably pass down the ArchSpec and work from that to make a portable triple if (m_cpu == k_i386) triple = "i386-unknown-unknown"; @@ -512,11 +516,16 @@ AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan) UnwindPlan up; UnwindPlan::Row row; int non_prologue_insn_count = 0; - Address m_cur_insn = m_func_bounds.GetBaseAddress (); + m_cur_insn = m_func_bounds.GetBaseAddress (); int current_func_text_offset = 0; int current_sp_bytes_offset_from_cfa = 0; UnwindPlan::Row::RegisterLocation regloc; + if (!m_cur_insn.IsValid()) + { + return false; + } + unwind_plan.SetPlanValidAddressRange (m_func_bounds); unwind_plan.SetRegisterKind (eRegisterKindLLDB); @@ -725,6 +734,11 @@ bool AssemblyParse_x86::find_first_non_prologue_insn (Address &address) { m_cur_insn = m_func_bounds.GetBaseAddress (); + if (!m_cur_insn.IsValid()) + { + return false; + } + while (m_func_bounds.ContainsFileAddress (m_cur_insn)) { Error error; diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp index d7d0a1005b5..9fdd05d9563 100644 --- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp +++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp @@ -35,20 +35,20 @@ UnwindLLDB::GetFrameCount() if (m_frames.empty()) { // First, set up the 0th (initial) frame - Cursor first_cursor; + 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.sctx, 0); + 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 0; } - if (!first_register_ctx->GetCFA (first_cursor.cfa)) + if (!first_register_ctx->GetCFA (first_cursor_sp->cfa)) { delete first_register_ctx; return 0; } - if (!first_register_ctx->GetPC (first_cursor.start_pc)) + if (!first_register_ctx->GetPC (first_cursor_sp->start_pc)) { delete first_register_ctx; return 0; @@ -56,16 +56,16 @@ UnwindLLDB::GetFrameCount() // Reuse the StackFrame provided by the processor native machine context for the first frame first_register_ctx->SetStackFrame (m_thread.GetStackFrameAtIndex(0).get()); RegisterContextSP temp_rcs(first_register_ctx); - first_cursor.reg_ctx = temp_rcs; - m_frames.push_back (first_cursor); + first_cursor_sp->reg_ctx = temp_rcs; + m_frames.push_back (first_cursor_sp); // Now walk up the rest of the stack while (1) { - Cursor cursor; + CursorSP cursor_sp(new Cursor); RegisterContextLLDB *register_ctx; int cur_idx = m_frames.size (); - register_ctx = new RegisterContextLLDB (m_thread, m_frames[cur_idx - 1].reg_ctx, cursor.sctx, cur_idx); + 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; @@ -76,7 +76,7 @@ UnwindLLDB::GetFrameCount() } break; } - if (!register_ctx->GetCFA (cursor.cfa)) + if (!register_ctx->GetCFA (cursor_sp->cfa)) { delete register_ctx; if (log) @@ -86,7 +86,7 @@ UnwindLLDB::GetFrameCount() } break; } - if (cursor.cfa == (addr_t) -1 || cursor.cfa == 1 || cursor.cfa == 0) + if (cursor_sp->cfa == (addr_t) -1 || cursor_sp->cfa == 1 || cursor_sp->cfa == 0) { delete register_ctx; if (log) @@ -96,7 +96,7 @@ UnwindLLDB::GetFrameCount() } break; } - if (!register_ctx->GetPC (cursor.start_pc)) + if (!register_ctx->GetPC (cursor_sp->start_pc)) { delete register_ctx; if (log) @@ -107,10 +107,10 @@ UnwindLLDB::GetFrameCount() break; } RegisterContextSP temp_rcs(register_ctx); - StackFrame *frame = new StackFrame(cur_idx, cur_idx, m_thread, temp_rcs, cursor.cfa, cursor.start_pc, &cursor.sctx); + StackFrame *frame = new StackFrame(cur_idx, cur_idx, m_thread, temp_rcs, cursor_sp->cfa, cursor_sp->start_pc, &(cursor_sp->sctx)); register_ctx->SetStackFrame (frame); - cursor.reg_ctx = temp_rcs; - m_frames.push_back (cursor); + cursor_sp->reg_ctx = temp_rcs; + m_frames.push_back (cursor_sp); } } return m_frames.size (); @@ -125,8 +125,8 @@ UnwindLLDB::GetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc) if (idx < m_frames.size ()) { - cfa = m_frames[idx].cfa; - pc = m_frames[idx].start_pc; + cfa = m_frames[idx]->cfa; + pc = m_frames[idx]->start_pc; return true; } return false; @@ -146,6 +146,6 @@ UnwindLLDB::CreateRegisterContextForFrame (StackFrame *frame) return m_thread.GetRegisterContext(); } if (idx < m_frames.size ()) - return m_frames[idx].reg_ctx.get(); + return m_frames[idx]->reg_ctx.get(); return NULL; } diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h index 5c1211719b7..f281269690d 100644 --- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h +++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h @@ -11,6 +11,7 @@ #define lldb_UnwindLLDB_h_ #include "lldb/lldb-private.h" +#include "lldb/lldb-types.h" #include "lldb/Target/Unwind.h" #include "lldb/Symbol/FuncUnwinders.h" #include "lldb/Symbol/UnwindPlan.h" @@ -57,7 +58,8 @@ private: Cursor () : start_pc (LLDB_INVALID_ADDRESS), cfa (LLDB_INVALID_ADDRESS), sctx(), reg_ctx() { } }; - std::vector<Cursor> m_frames; + typedef lldb::SharedPtr<Cursor>::Type CursorSP; + std::vector<CursorSP> m_frames; //------------------------------------------------------------------ // For UnwindLLDB only |

