diff options
Diffstat (limited to 'lldb/source/Plugins')
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 |

