From e576ab2996b5fa4facf2bf7e73cc4679cb17c133 Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Tue, 15 Feb 2011 00:19:15 +0000 Subject: [PATCH] All UnwindPlan objects are now passed around as shared pointers. ArchDefaultUnwindPlan plug-in interfaces are now cached per architecture instead of being leaked for every frame. Split the ArchDefaultUnwindPlan_x86 into ArchDefaultUnwindPlan_x86_64 and ArchDefaultUnwindPlan_i386 interfaces. There were sporadic crashes that were due to something leaking or being destroyed when doing stack crawls. This patch should clear up these issues. llvm-svn: 125541 --- lldb/include/lldb/Symbol/FuncUnwinders.h | 16 +- .../lldb/Utility/ArchDefaultUnwindPlan.h | 4 +- lldb/include/lldb/lldb-forward-rtti.h | 2 + .../Utility/ArchDefaultUnwindPlan-x86.cpp | 188 ++++++++---- .../Utility/ArchDefaultUnwindPlan-x86.h | 63 +++- .../Process/Utility/RegisterContextLLDB.cpp | 286 ++++++++---------- .../Process/Utility/RegisterContextLLDB.h | 15 +- .../Plugins/Process/Utility/UnwindLLDB.cpp | 14 +- .../Plugins/Process/Utility/UnwindLLDB.h | 12 +- .../gdb-remote/GDBRemoteRegisterContext.cpp | 6 +- .../gdb-remote/GDBRemoteRegisterContext.h | 2 +- .../Process/gdb-remote/ProcessGDBRemote.cpp | 30 +- .../Process/gdb-remote/ThreadGDBRemote.cpp | 9 +- .../Process/gdb-remote/ThreadGDBRemote.h | 2 +- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 28 +- .../SymbolFile/DWARF/SymbolFileDWARF.h | 3 + .../DWARF/SymbolFileDWARFDebugMap.h | 8 + lldb/source/Symbol/FuncUnwinders.cpp | 61 ++-- lldb/source/Utility/ArchDefaultUnwindPlan.cpp | 26 +- lldb/source/lldb.cpp | 6 +- 20 files changed, 471 insertions(+), 310 deletions(-) diff --git a/lldb/include/lldb/Symbol/FuncUnwinders.h b/lldb/include/lldb/Symbol/FuncUnwinders.h index 51c7ba6985a4..5df1c7184ead 100644 --- a/lldb/include/lldb/Symbol/FuncUnwinders.h +++ b/lldb/include/lldb/Symbol/FuncUnwinders.h @@ -43,16 +43,16 @@ public: // On architectures where the pc points to the next instruction that will execute, this // offset value will have already been decremented by 1 to stay within the bounds of the // correct function body. - UnwindPlan* + lldb::UnwindPlanSP GetUnwindPlanAtCallSite (int current_offset); - UnwindPlan* + lldb::UnwindPlanSP GetUnwindPlanAtNonCallSite (lldb_private::Thread& thread); - UnwindPlan* + lldb::UnwindPlanSP GetUnwindPlanFastUnwind (lldb_private::Thread& Thread); - UnwindPlan* + lldb::UnwindPlanSP GetUnwindPlanArchitectureDefault (lldb_private::Thread& thread); Address& @@ -74,10 +74,10 @@ private: AddressRange m_range; Mutex m_mutex; - std::auto_ptr m_unwind_at_call_site_ap; - std::auto_ptr m_unwind_at_non_call_site_ap; - std::auto_ptr m_unwind_fast_ap; - UnwindPlan *m_unwind_arch_default; + lldb::UnwindPlanSP m_unwind_plan_call_site_sp; + lldb::UnwindPlanSP m_unwind_plan_non_call_site_sp; + lldb::UnwindPlanSP m_unwind_plan_fast_sp; + lldb::UnwindPlanSP m_unwind_plan_arch_default_sp; bool m_tried_unwind_at_call_site:1, m_tried_unwind_at_non_call_site:1, diff --git a/lldb/include/lldb/Utility/ArchDefaultUnwindPlan.h b/lldb/include/lldb/Utility/ArchDefaultUnwindPlan.h index 3a887c3b1078..ba21bf29d623 100644 --- a/lldb/include/lldb/Utility/ArchDefaultUnwindPlan.h +++ b/lldb/include/lldb/Utility/ArchDefaultUnwindPlan.h @@ -23,10 +23,10 @@ public: virtual ~ArchDefaultUnwindPlan(); - virtual lldb_private::UnwindPlan* + virtual lldb::UnwindPlanSP GetArchDefaultUnwindPlan (Thread& thread, Address current_pc) = 0; - static ArchDefaultUnwindPlan* + static lldb::ArchDefaultUnwindPlanSP FindPlugin (const ArchSpec &arch); protected: diff --git a/lldb/include/lldb/lldb-forward-rtti.h b/lldb/include/lldb/lldb-forward-rtti.h index 29aea763cae4..b2d4e158987c 100644 --- a/lldb/include/lldb/lldb-forward-rtti.h +++ b/lldb/include/lldb/lldb-forward-rtti.h @@ -21,6 +21,7 @@ namespace lldb { typedef SharedPtr::Type ABISP; typedef SharedPtr::Type AddressResolverSP; + typedef SharedPtr::Type ArchDefaultUnwindPlanSP; typedef SharedPtr::Type BatonSP; typedef SharedPtr::Type BlockSP; typedef SharedPtr::Type BreakpointSP; @@ -66,6 +67,7 @@ namespace lldb { typedef SharedPtr::Type TypeSP; typedef SharedPtr::Type FuncUnwindersSP; typedef SharedPtr::Type UserSettingsControllerSP; + typedef SharedPtr::Type UnwindPlanSP; typedef SharedPtr::Type ValueObjectSP; typedef SharedPtr::Type VariableSP; typedef SharedPtr::Type VariableListSP; diff --git a/lldb/source/Plugins/Process/Utility/ArchDefaultUnwindPlan-x86.cpp b/lldb/source/Plugins/Process/Utility/ArchDefaultUnwindPlan-x86.cpp index 289429d0c25a..6824b799dd76 100644 --- a/lldb/source/Plugins/Process/Utility/ArchDefaultUnwindPlan-x86.cpp +++ b/lldb/source/Plugins/Process/Utility/ArchDefaultUnwindPlan-x86.cpp @@ -8,115 +8,182 @@ //===----------------------------------------------------------------------===// #include "ArchDefaultUnwindPlan-x86.h" -#include "llvm/Support/MachO.h" -#include "lldb/lldb-private.h" -#include "lldb/Utility/ArchDefaultUnwindPlan.h" #include "lldb/Core/ArchSpec.h" #include "lldb/Core/PluginManager.h" -#include "lldb/lldb-enumerations.h" +#include "lldb/Utility/ArchDefaultUnwindPlan.h" using namespace lldb; using namespace lldb_private; -lldb_private::UnwindPlan* -ArchDefaultUnwindPlan_x86::GetArchDefaultUnwindPlan (Thread& thread, Address current_pc) -{ - if (m_cpu == llvm::MachO::CPUTypeX86_64) - { - return &m_64bit_default; - } - if (m_cpu == llvm::MachO::CPUTypeI386) - { - return &m_32bit_default; - } - return NULL; -} - lldb_private::ArchDefaultUnwindPlan * -ArchDefaultUnwindPlan_x86::CreateInstance (const lldb_private::ArchSpec &arch) +ArchDefaultUnwindPlan_x86_64::CreateInstance (const lldb_private::ArchSpec &arch) { - uint32_t cpu = arch.GetCPUType (); - if (cpu != llvm::MachO::CPUTypeX86_64 && cpu != llvm::MachO::CPUTypeI386) - return NULL; - - return new ArchDefaultUnwindPlan_x86 (cpu); + if (arch.GetGenericCPUType () == ArchSpec::eCPU_x86_64) + return new ArchDefaultUnwindPlan_x86_64 (); + return NULL; } -ArchDefaultUnwindPlan_x86::ArchDefaultUnwindPlan_x86(int cpu) : +ArchDefaultUnwindPlan_x86_64::ArchDefaultUnwindPlan_x86_64() : lldb_private::ArchDefaultUnwindPlan(), - m_cpu(cpu), - m_32bit_default(), - m_64bit_default() + m_unwind_plan_sp (new UnwindPlan) { UnwindPlan::Row row; UnwindPlan::Row::RegisterLocation regloc; - m_32bit_default.SetRegisterKind (eRegisterKindGeneric); + m_unwind_plan_sp->SetRegisterKind (eRegisterKindGeneric); row.SetCFARegister (LLDB_REGNUM_GENERIC_FP); - row.SetCFAOffset (2 * 4); + row.SetCFAOffset (2 * 8); row.SetOffset (0); - regloc.SetAtCFAPlusOffset (2 * -4); + regloc.SetAtCFAPlusOffset (2 * -8); row.SetRegisterInfo (LLDB_REGNUM_GENERIC_FP, regloc); - regloc.SetAtCFAPlusOffset (1 * -4); + regloc.SetAtCFAPlusOffset (1 * -8); row.SetRegisterInfo (LLDB_REGNUM_GENERIC_PC, regloc); regloc.SetIsCFAPlusOffset (0); row.SetRegisterInfo (LLDB_REGNUM_GENERIC_SP, regloc); - m_32bit_default.AppendRow (row); - m_32bit_default.SetSourceName ("architectural default"); + m_unwind_plan_sp->AppendRow (row); + m_unwind_plan_sp->SetSourceName ("x86_64 architectural default"); +} + +//------------------------------------------------------------------ +// PluginInterface protocol in UnwindAssemblyParser_x86 +//------------------------------------------------------------------ + +const char * +ArchDefaultUnwindPlan_x86_64::GetPluginName() +{ + return "ArchDefaultUnwindPlan_x86_64"; +} + +const char * +ArchDefaultUnwindPlan_x86_64::GetShortPluginName() +{ + return "lldb.arch-default-unwind-plan.x86-64"; +} + + +uint32_t +ArchDefaultUnwindPlan_x86_64::GetPluginVersion() +{ + return 1; +} + +void +ArchDefaultUnwindPlan_x86_64::GetPluginCommandHelp (const char *command, Stream *strm) +{ +} + +Error +ArchDefaultUnwindPlan_x86_64::ExecutePluginCommand (Args &command, Stream *strm) +{ + Error error; + error.SetErrorString("No plug-in command are currently supported."); + return error; +} + +Log * +ArchDefaultUnwindPlan_x86_64::EnablePluginLogging (Stream *strm, Args &command) +{ + return NULL; +} + +void +ArchDefaultUnwindPlan_x86_64::Initialize() +{ + PluginManager::RegisterPlugin (GetPluginNameStatic(), + GetPluginDescriptionStatic(), + CreateInstance); +} + +void +ArchDefaultUnwindPlan_x86_64::Terminate() +{ + PluginManager::UnregisterPlugin (CreateInstance); +} + + +const char * +ArchDefaultUnwindPlan_x86_64::GetPluginNameStatic() +{ + return "ArchDefaultUnwindPlan_x86_64"; +} + +const char * +ArchDefaultUnwindPlan_x86_64::GetPluginDescriptionStatic() +{ + return "x86_64 architecture default unwind plan assembly plugin."; +} + +UnwindPlanSP +ArchDefaultUnwindPlan_x86_64::GetArchDefaultUnwindPlan (Thread& thread, Address current_pc) +{ + return m_unwind_plan_sp; +} + + + +lldb_private::ArchDefaultUnwindPlan * +ArchDefaultUnwindPlan_i386::CreateInstance (const lldb_private::ArchSpec &arch) +{ + if (arch.GetGenericCPUType () == ArchSpec::eCPU_i386) + return new ArchDefaultUnwindPlan_i386 (); + return NULL; +} - row.Clear(); +ArchDefaultUnwindPlan_i386::ArchDefaultUnwindPlan_i386() : + lldb_private::ArchDefaultUnwindPlan(), + m_unwind_plan_sp (new UnwindPlan) +{ + UnwindPlan::Row row; + UnwindPlan::Row::RegisterLocation regloc; - m_64bit_default.SetRegisterKind (eRegisterKindGeneric); + m_unwind_plan_sp->SetRegisterKind (eRegisterKindGeneric); row.SetCFARegister (LLDB_REGNUM_GENERIC_FP); - row.SetCFAOffset (2 * 8); + row.SetCFAOffset (2 * 4); row.SetOffset (0); - regloc.SetAtCFAPlusOffset (2 * -8); + regloc.SetAtCFAPlusOffset (2 * -4); row.SetRegisterInfo (LLDB_REGNUM_GENERIC_FP, regloc); - regloc.SetAtCFAPlusOffset (1 * -8); + regloc.SetAtCFAPlusOffset (1 * -4); row.SetRegisterInfo (LLDB_REGNUM_GENERIC_PC, regloc); regloc.SetIsCFAPlusOffset (0); row.SetRegisterInfo (LLDB_REGNUM_GENERIC_SP, regloc); - m_64bit_default.AppendRow (row); - m_64bit_default.SetSourceName ("architectural default"); + m_unwind_plan_sp->AppendRow (row); + m_unwind_plan_sp->SetSourceName ("i386 architectural default"); } - - - //------------------------------------------------------------------ // PluginInterface protocol in UnwindAssemblyParser_x86 //------------------------------------------------------------------ const char * -ArchDefaultUnwindPlan_x86::GetPluginName() +ArchDefaultUnwindPlan_i386::GetPluginName() { - return "ArchDefaultUnwindPlan_x86"; + return "ArchDefaultUnwindPlan_i386"; } const char * -ArchDefaultUnwindPlan_x86::GetShortPluginName() +ArchDefaultUnwindPlan_i386::GetShortPluginName() { return "archdefaultunwindplan.x86"; } uint32_t -ArchDefaultUnwindPlan_x86::GetPluginVersion() +ArchDefaultUnwindPlan_i386::GetPluginVersion() { return 1; } void -ArchDefaultUnwindPlan_x86::GetPluginCommandHelp (const char *command, Stream *strm) +ArchDefaultUnwindPlan_i386::GetPluginCommandHelp (const char *command, Stream *strm) { } Error -ArchDefaultUnwindPlan_x86::ExecutePluginCommand (Args &command, Stream *strm) +ArchDefaultUnwindPlan_i386::ExecutePluginCommand (Args &command, Stream *strm) { Error error; error.SetErrorString("No plug-in command are currently supported."); @@ -124,13 +191,13 @@ ArchDefaultUnwindPlan_x86::ExecutePluginCommand (Args &command, Stream *strm) } Log * -ArchDefaultUnwindPlan_x86::EnablePluginLogging (Stream *strm, Args &command) +ArchDefaultUnwindPlan_i386::EnablePluginLogging (Stream *strm, Args &command) { return NULL; } void -ArchDefaultUnwindPlan_x86::Initialize() +ArchDefaultUnwindPlan_i386::Initialize() { PluginManager::RegisterPlugin (GetPluginNameStatic(), GetPluginDescriptionStatic(), @@ -138,20 +205,27 @@ ArchDefaultUnwindPlan_x86::Initialize() } void -ArchDefaultUnwindPlan_x86::Terminate() +ArchDefaultUnwindPlan_i386::Terminate() { PluginManager::UnregisterPlugin (CreateInstance); } const char * -ArchDefaultUnwindPlan_x86::GetPluginNameStatic() +ArchDefaultUnwindPlan_i386::GetPluginNameStatic() { - return "ArchDefaultUnwindPlan_x86"; + return "ArchDefaultUnwindPlan_i386"; } const char * -ArchDefaultUnwindPlan_x86::GetPluginDescriptionStatic() +ArchDefaultUnwindPlan_i386::GetPluginDescriptionStatic() +{ + return "i386 architecture default unwind plan assembly plugin."; +} + +UnwindPlanSP +ArchDefaultUnwindPlan_i386::GetArchDefaultUnwindPlan (Thread& thread, Address current_pc) { - return "i386 and x86_64 architecture default unwind plan assembly plugin."; + return m_unwind_plan_sp; } + diff --git a/lldb/source/Plugins/Process/Utility/ArchDefaultUnwindPlan-x86.h b/lldb/source/Plugins/Process/Utility/ArchDefaultUnwindPlan-x86.h index cf0cc05504f3..d3f4b26ee2f6 100644 --- a/lldb/source/Plugins/Process/Utility/ArchDefaultUnwindPlan-x86.h +++ b/lldb/source/Plugins/Process/Utility/ArchDefaultUnwindPlan-x86.h @@ -17,13 +17,13 @@ namespace lldb_private { -class ArchDefaultUnwindPlan_x86 : public lldb_private::ArchDefaultUnwindPlan +class ArchDefaultUnwindPlan_x86_64 : public lldb_private::ArchDefaultUnwindPlan { public: - ~ArchDefaultUnwindPlan_x86 () { } + ~ArchDefaultUnwindPlan_x86_64 () { } - virtual lldb_private::UnwindPlan* + virtual lldb::UnwindPlanSP GetArchDefaultUnwindPlan (Thread& thread, Address current_pc); static lldb_private::ArchDefaultUnwindPlan * @@ -63,11 +63,60 @@ public: EnablePluginLogging (lldb_private::Stream *strm, lldb_private::Args &command); private: - ArchDefaultUnwindPlan_x86(int cpu); // Call CreateInstance instead. + ArchDefaultUnwindPlan_x86_64(); // Call CreateInstance instead. - int m_cpu; - lldb_private::UnwindPlan m_32bit_default; - lldb_private::UnwindPlan m_64bit_default; + lldb::UnwindPlanSP m_unwind_plan_sp; +}; + +class ArchDefaultUnwindPlan_i386 : public lldb_private::ArchDefaultUnwindPlan +{ +public: + + ~ArchDefaultUnwindPlan_i386 () { } + + virtual lldb::UnwindPlanSP + GetArchDefaultUnwindPlan (Thread& thread, Address current_pc); + + static lldb_private::ArchDefaultUnwindPlan * + CreateInstance (const lldb_private::ArchSpec &arch); + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + static void + Initialize(); + + static void + Terminate(); + + static const char * + GetPluginNameStatic(); + + static const char * + GetPluginDescriptionStatic(); + + virtual const char * + GetPluginName(); + + virtual const char * + GetShortPluginName(); + + virtual uint32_t + GetPluginVersion(); + + virtual void + GetPluginCommandHelp (const char *command, lldb_private::Stream *strm); + + virtual lldb_private::Error + ExecutePluginCommand (lldb_private::Args &command, lldb_private::Stream *strm); + + virtual lldb_private::Log * + EnablePluginLogging (lldb_private::Stream *strm, lldb_private::Args &command); + +private: + ArchDefaultUnwindPlan_i386(); // Call CreateInstance instead. + + lldb::UnwindPlanSP m_unwind_plan_sp; }; diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp index c508b86a1634..621d7fc4ca37 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -34,7 +34,7 @@ using namespace lldb_private; RegisterContextLLDB::RegisterContextLLDB ( Thread& thread, - const RegisterContextSP &next_frame, + const SharedPtr &next_frame, SymbolContext& sym_ctx, uint32_t frame_number ) : @@ -48,8 +48,8 @@ RegisterContextLLDB::RegisterContextLLDB m_start_pc (), m_current_pc (), m_frame_number (frame_number), - m_full_unwind_plan(NULL), - m_fast_unwind_plan(NULL), + m_full_unwind_plan_sp (), + m_fast_unwind_plan_sp (), m_frame_type (-1), m_current_offset (0), m_current_offset_backed_up_one (0), @@ -68,20 +68,9 @@ RegisterContextLLDB::RegisterContextLLDB } // This same code exists over in the GetFullUnwindPlanForFrame() but it may not have been executed yet - bool behaves_like_zeroth_frame = false; - if (IsFrameZero()) - { - behaves_like_zeroth_frame = true; - } - if (!IsFrameZero() && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eSigtrampFrame) - { - behaves_like_zeroth_frame = true; - } - if (!IsFrameZero() && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eDebuggerFrame) - { - behaves_like_zeroth_frame = true; - } - if (behaves_like_zeroth_frame) + if (IsFrameZero() + || m_next_frame->m_frame_type == eSigtrampFrame + || m_next_frame->m_frame_type == eDebuggerFrame) { m_all_registers_available = true; } @@ -124,6 +113,7 @@ RegisterContextLLDB::InitializeZerothFrame() if (addr_range.GetBaseAddress().IsValid()) { m_start_pc = addr_range.GetBaseAddress(); + assert (frame_sp->GetFrameCodeAddress().GetSection() == m_start_pc.GetSection()); m_current_offset = frame_sp->GetFrameCodeAddress().GetOffset() - m_start_pc.GetOffset(); m_current_offset_backed_up_one = m_current_offset; } @@ -136,16 +126,16 @@ RegisterContextLLDB::InitializeZerothFrame() // We've set m_frame_type and m_sym_ctx before these calls. - m_fast_unwind_plan = GetFastUnwindPlanForFrame (); - m_full_unwind_plan = GetFullUnwindPlanForFrame (); - + m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame (); + m_full_unwind_plan_sp = GetFullUnwindPlanForFrame (); + const UnwindPlan::Row *active_row = NULL; int cfa_offset = 0; int row_register_kind; - if (m_full_unwind_plan && m_full_unwind_plan->PlanValidAtAddress (m_current_pc)) + if (m_full_unwind_plan_sp && m_full_unwind_plan_sp->PlanValidAtAddress (m_current_pc)) { - active_row = m_full_unwind_plan->GetRowForFunctionOffset (m_current_offset); - row_register_kind = m_full_unwind_plan->GetRegisterKind (); + active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); + row_register_kind = m_full_unwind_plan_sp->GetRegisterKind (); } if (active_row == NULL) @@ -189,7 +179,7 @@ RegisterContextLLDB::InitializeZerothFrame() m_frame_number, (uint64_t) m_current_pc.GetLoadAddress (&m_thread.GetProcess().GetTarget()), (uint64_t) m_cfa, - m_full_unwind_plan->GetSourceName().GetCString()); + m_full_unwind_plan_sp->GetSourceName().GetCString()); } } @@ -205,7 +195,8 @@ RegisterContextLLDB::InitializeNonZerothFrame() m_frame_type = eNotAValidFrame; return; } - if (!((RegisterContextLLDB*)m_next_frame.get())->IsValid()) + + if (!m_next_frame->IsValid()) { m_frame_type = eNotAValidFrame; return; @@ -244,20 +235,20 @@ RegisterContextLLDB::InitializeNonZerothFrame() log->Printf("%*sFrame %u using architectural default unwind method", m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number); } - ArchSpec arch = m_thread.GetProcess().GetTarget().GetArchitecture (); - ArchDefaultUnwindPlan *arch_default = ArchDefaultUnwindPlan::FindPlugin (arch); - if (arch_default) + const ArchSpec &arch = m_thread.GetProcess().GetTarget().GetArchitecture (); + ArchDefaultUnwindPlanSP arch_default_sp (ArchDefaultUnwindPlan::FindPlugin (arch)); + if (arch_default_sp) { - m_fast_unwind_plan = NULL; - m_full_unwind_plan = arch_default->GetArchDefaultUnwindPlan (m_thread, m_current_pc); + m_fast_unwind_plan_sp.reset(); + m_full_unwind_plan_sp = arch_default_sp->GetArchDefaultUnwindPlan (m_thread, m_current_pc); m_frame_type = eNormalFrame; m_all_registers_available = false; m_current_offset = -1; m_current_offset_backed_up_one = -1; addr_t cfa_regval; - int row_register_kind = m_full_unwind_plan->GetRegisterKind (); - uint32_t cfa_regnum = m_full_unwind_plan->GetRowForFunctionOffset(0)->GetCFARegister(); - int cfa_offset = m_full_unwind_plan->GetRowForFunctionOffset(0)->GetCFAOffset(); + int row_register_kind = m_full_unwind_plan_sp->GetRegisterKind (); + uint32_t cfa_regnum = m_full_unwind_plan_sp->GetRowForFunctionOffset(0)->GetCFARegister(); + int cfa_offset = m_full_unwind_plan_sp->GetRowForFunctionOffset(0)->GetCFAOffset(); if (!ReadGPRValue (row_register_kind, cfa_regnum, cfa_regval)) { if (log) @@ -315,8 +306,8 @@ RegisterContextLLDB::InitializeNonZerothFrame() // Or if we're in the middle of the stack (and not "above" an asynchronous event like sigtramp), // and our "current" pc is the start of a function... if (m_sym_ctx_valid - && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type != eSigtrampFrame - && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type != eDebuggerFrame + && m_next_frame->m_frame_type != eSigtrampFrame + && m_next_frame->m_frame_type != eDebuggerFrame && addr_range.GetBaseAddress().IsValid() && addr_range.GetBaseAddress().GetSection() == m_current_pc.GetSection() && addr_range.GetBaseAddress().GetOffset() == m_current_pc.GetOffset()) @@ -374,7 +365,7 @@ RegisterContextLLDB::InitializeNonZerothFrame() } // We've set m_frame_type and m_sym_ctx before this call. - m_fast_unwind_plan = GetFastUnwindPlanForFrame (); + m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame (); const UnwindPlan::Row *active_row = NULL; int cfa_offset = 0; @@ -383,18 +374,18 @@ RegisterContextLLDB::InitializeNonZerothFrame() // Try to get by with just the fast UnwindPlan if possible - the full UnwindPlan may be expensive to get // (e.g. if we have to parse the entire eh_frame section of an ObjectFile for the first time.) - if (m_fast_unwind_plan && m_fast_unwind_plan->PlanValidAtAddress (m_current_pc)) + if (m_fast_unwind_plan_sp && m_fast_unwind_plan_sp->PlanValidAtAddress (m_current_pc)) { - active_row = m_fast_unwind_plan->GetRowForFunctionOffset (m_current_offset); - row_register_kind = m_fast_unwind_plan->GetRegisterKind (); + active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); + row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind (); } else { - m_full_unwind_plan = GetFullUnwindPlanForFrame (); - if (m_full_unwind_plan && m_full_unwind_plan->PlanValidAtAddress (m_current_pc)) + m_full_unwind_plan_sp = GetFullUnwindPlanForFrame (); + if (m_full_unwind_plan_sp && m_full_unwind_plan_sp->PlanValidAtAddress (m_current_pc)) { - active_row = m_full_unwind_plan->GetRowForFunctionOffset (m_current_offset); - row_register_kind = m_full_unwind_plan->GetRegisterKind (); + active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); + row_register_kind = m_full_unwind_plan_sp->GetRegisterKind (); } } @@ -460,49 +451,47 @@ RegisterContextLLDB::IsFrameZero () const // 3. m_current_pc should have the current pc value for this frame // 4. m_current_offset_backed_up_one should have the current byte offset into the function, maybe backed up by 1, -1 if unknown -UnwindPlan * +UnwindPlanSP RegisterContextLLDB::GetFastUnwindPlanForFrame () { + UnwindPlanSP unwind_plan_sp; if (!m_current_pc.IsValid() || m_current_pc.GetModule() == NULL || m_current_pc.GetModule()->GetObjectFile() == NULL) - { - return NULL; - } + return unwind_plan_sp; if (IsFrameZero ()) - { - return NULL; - } + return unwind_plan_sp; - FuncUnwindersSP fu; - fu = m_current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx); - if (fu.get() == NULL) - { - return NULL; - } + FuncUnwindersSP func_unwinders_sp (m_current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx)); + if (!func_unwinders_sp) + return unwind_plan_sp; // If we're in _sigtramp(), unwinding past this frame requires special knowledge. if (m_frame_type == eSigtrampFrame || m_frame_type == eDebuggerFrame) - { - return NULL; - } + return unwind_plan_sp; - if (fu->GetUnwindPlanFastUnwind (m_thread) - && fu->GetUnwindPlanFastUnwind (m_thread)->PlanValidAtAddress (m_current_pc)) + unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind (m_thread); + if (unwind_plan_sp) { - LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); - if (log && IsLogVerbose()) + if (unwind_plan_sp->PlanValidAtAddress (m_current_pc)) { - const char *has_fast = ""; - if (m_fast_unwind_plan) - has_fast = ", and has a fast UnwindPlan"; - log->Printf("%*sFrame %u frame has a fast UnwindPlan", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number); + LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); + if (log && IsLogVerbose()) + { + const char *has_fast = ""; + if (m_fast_unwind_plan_sp) + has_fast = ", and has a fast UnwindPlan"; + log->Printf("%*sFrame %u frame has a fast UnwindPlan", + m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number); + } + m_frame_type = eNormalFrame; + return unwind_plan_sp; + } + else + { + unwind_plan_sp.reset(); } - m_frame_type = eNormalFrame; - return fu->GetUnwindPlanFastUnwind (m_thread); } - - return NULL; + return unwind_plan_sp; } // On entry to this method, @@ -512,37 +501,25 @@ RegisterContextLLDB::GetFastUnwindPlanForFrame () // 3. m_current_pc should have the current pc value for this frame // 4. m_current_offset_backed_up_one should have the current byte offset into the function, maybe backed up by 1, -1 if unknown -UnwindPlan * +UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame () { + UnwindPlanSP unwind_plan_sp; LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); - UnwindPlan *up; - UnwindPlan *arch_default_up = NULL; - ArchSpec arch = m_thread.GetProcess().GetTarget().GetArchitecture (); - ArchDefaultUnwindPlan *arch_default = ArchDefaultUnwindPlan::FindPlugin (arch); - if (arch_default) - { - arch_default_up = arch_default->GetArchDefaultUnwindPlan (m_thread, m_current_pc); - } + UnwindPlanSP arch_default_unwind_plan_sp; + const ArchSpec &arch = m_thread.GetProcess().GetTarget().GetArchitecture (); + ArchDefaultUnwindPlanSP arch_default_sp (ArchDefaultUnwindPlan::FindPlugin (arch)); + if (arch_default_sp) + arch_default_unwind_plan_sp = arch_default_sp->GetArchDefaultUnwindPlan (m_thread, m_current_pc); bool behaves_like_zeroth_frame = false; - if (IsFrameZero ()) - { - behaves_like_zeroth_frame = true; - } - if (!IsFrameZero () && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eSigtrampFrame) + if (IsFrameZero () + || m_next_frame->m_frame_type == eSigtrampFrame + || m_next_frame->m_frame_type == eDebuggerFrame) { behaves_like_zeroth_frame = true; - } - if (!IsFrameZero () && ((RegisterContextLLDB*) m_next_frame.get())->m_frame_type == eDebuggerFrame) - { - 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) - { + // If this frame behaves like a 0th frame (currently executing or + // interrupted asynchronously), all registers can be retrieved. m_all_registers_available = true; } @@ -550,20 +527,20 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame () if (!m_current_pc.IsValid() || m_current_pc.GetModule() == NULL || m_current_pc.GetModule()->GetObjectFile() == NULL) { m_frame_type = eNormalFrame; - return arch_default_up; + return arch_default_unwind_plan_sp; } - FuncUnwindersSP fu; + FuncUnwindersSP func_unwinders_sp; if (m_sym_ctx_valid) { - fu = m_current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx); + func_unwinders_sp = 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) + if (!func_unwinders_sp) { m_frame_type = eNormalFrame; - return arch_default_up; + return arch_default_unwind_plan_sp; } // If we're in _sigtramp(), unwinding past this frame requires special knowledge. On Mac OS X this knowledge @@ -572,53 +549,54 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame () // how to unwind out of sigtramp. if (m_frame_type == eSigtrampFrame) { - m_fast_unwind_plan = NULL; - up = fu->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one); - if (up && up->PlanValidAtAddress (m_current_pc)) - { - return up; - } + m_fast_unwind_plan_sp.reset(); + unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one); + if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc)) + return unwind_plan_sp; } // Typically the NonCallSite UnwindPlan is the unwind created by inspecting the assembly language instructions - up = fu->GetUnwindPlanAtNonCallSite (m_thread); - if (behaves_like_zeroth_frame && up && up->PlanValidAtAddress (m_current_pc)) + if (behaves_like_zeroth_frame) { - if (log && IsLogVerbose()) + unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (m_thread); + if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc)) { - log->Printf("%*sFrame %u frame uses %s for full UnwindPlan", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - up->GetSourceName().GetCString()); + if (log && IsLogVerbose()) + { + log->Printf("%*sFrame %u frame uses %s for full UnwindPlan", + m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, + unwind_plan_sp->GetSourceName().GetCString()); + } + return unwind_plan_sp; } - return up; } // Typically this is unwind info from an eh_frame section intended for exception handling; only valid at call sites - up = fu->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one); - if (up && up->PlanValidAtAddress (m_current_pc)) + unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one); + if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc)) { if (log && IsLogVerbose()) { log->Printf("%*sFrame %u frame uses %s for full UnwindPlan", m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - up->GetSourceName().GetCString()); + unwind_plan_sp->GetSourceName().GetCString()); } - return up; + return unwind_plan_sp; } // We'd prefer to use an UnwindPlan intended for call sites when we're at a call site but if we've // struck out on that, fall back to using the non-call-site assembly inspection UnwindPlan if possible. - up = fu->GetUnwindPlanAtNonCallSite (m_thread); - if (up && up->PlanValidAtAddress (m_current_pc)) + unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (m_thread); + if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc)) { if (log && IsLogVerbose()) { log->Printf("%*sFrame %u frame uses %s for full UnwindPlan", m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - up->GetSourceName().GetCString()); + unwind_plan_sp->GetSourceName().GetCString()); } - return up; + return unwind_plan_sp; } // If nothing else, use the architectural default UnwindPlan and hope that does the job. @@ -626,9 +604,9 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame () { log->Printf("%*sFrame %u frame uses %s for full UnwindPlan", m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - arch_default_up->GetSourceName().GetCString()); + arch_default_unwind_plan_sp->GetSourceName().GetCString()); } - return arch_default_up; + return arch_default_unwind_plan_sp; } @@ -812,9 +790,9 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); // Have we already found this register location? - std::map::const_iterator iterator; - if (m_registers.size() > 0) + if (!m_registers.empty()) { + std::map::const_iterator iterator; iterator = m_registers.find (lldb_regnum); if (iterator != m_registers.end()) { @@ -843,10 +821,10 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc bool have_unwindplan_regloc = false; int unwindplan_registerkind = -1; - if (m_fast_unwind_plan) + if (m_fast_unwind_plan_sp) { - const UnwindPlan::Row *active_row = m_fast_unwind_plan->GetRowForFunctionOffset (m_current_offset); - unwindplan_registerkind = m_fast_unwind_plan->GetRegisterKind (); + const UnwindPlan::Row *active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); + unwindplan_registerkind = m_fast_unwind_plan_sp->GetRegisterKind (); uint32_t row_regnum; if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum)) { @@ -872,15 +850,14 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc if (!have_unwindplan_regloc) { - // 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 (); - } - if (m_full_unwind_plan) + // m_full_unwind_plan_sp being NULL means that we haven't tried to find a full UnwindPlan yet + if (!m_full_unwind_plan_sp) + m_full_unwind_plan_sp = GetFullUnwindPlanForFrame (); + + if (m_full_unwind_plan_sp) { - const UnwindPlan::Row *active_row = m_full_unwind_plan->GetRowForFunctionOffset (m_current_offset); - unwindplan_registerkind = m_full_unwind_plan->GetRegisterKind (); + const UnwindPlan::Row *active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); + unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind (); uint32_t row_regnum; if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum)) { @@ -905,7 +882,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc { log->Printf("%*sFrame %u supplying caller's saved reg %d's location using %s UnwindPlan", m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum, m_full_unwind_plan->GetSourceName().GetCString()); + lldb_regnum, m_full_unwind_plan_sp->GetSourceName().GetCString()); } } } @@ -915,7 +892,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc { // If a volatile register is being requested, we don't want to forward m_next_frame's register contents // up the stack -- the register is not retrievable at this frame. - ArchSpec arch = m_thread.GetProcess().GetTarget().GetArchitecture (); + const ArchSpec &arch = m_thread.GetProcess().GetTarget().GetArchitecture (); ArchVolatileRegs *volatile_regs = ArchVolatileRegs::FindPlugin (arch); if (volatile_regs && volatile_regs->RegisterIsVolatile (m_thread, lldb_regnum)) { @@ -928,11 +905,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc return false; } - if (!IsFrameZero ()) - { - return ((RegisterContextLLDB*)m_next_frame.get())->SavedLocationForRegister (lldb_regnum, regloc); - } - else + if (IsFrameZero ()) { // This is frame 0 - we should return the actual live register context value RegisterLocation new_regloc; @@ -942,6 +915,10 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc regloc = new_regloc; return true; } + else + { + return m_next_frame->SavedLocationForRegister (lldb_regnum, regloc); + } if (log) { log->Printf("%*sFrame %u could not supply caller's reg %d location", @@ -968,11 +945,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc if (unwindplan_regloc.IsSame()) { - if (!IsFrameZero ()) - { - return ((RegisterContextLLDB*)m_next_frame.get())->SavedLocationForRegister (lldb_regnum, regloc); - } - else + if (IsFrameZero ()) { if (log) { @@ -982,6 +955,10 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc } return false; } + else + { + return m_next_frame->SavedLocationForRegister (lldb_regnum, regloc); + } } if (unwindplan_regloc.IsCFAPlusOffset()) @@ -1116,14 +1093,11 @@ RegisterContextLLDB::ReadGPRValue (int register_kind, uint32_t regnum, addr_t &v value = data.GetAddress (&offset); return true; } - else - { - return false; - } + return false; } RegisterLocation regloc; - if (!((RegisterContextLLDB*)m_next_frame.get())->SavedLocationForRegister (lldb_regnum, regloc)) + if (!m_next_frame->SavedLocationForRegister (lldb_regnum, regloc)) { return false; } @@ -1166,7 +1140,7 @@ RegisterContextLLDB::ReadRegisterBytes (uint32_t lldb_reg, DataExtractor& data) RegisterLocation regloc; // Find out where the NEXT frame saved THIS frame's register contents - if (!((RegisterContextLLDB*)m_next_frame.get())->SavedLocationForRegister (lldb_reg, regloc)) + if (!m_next_frame->SavedLocationForRegister (lldb_reg, regloc)) return false; return ReadRegisterBytesFromRegisterLocation (lldb_reg, regloc, data); @@ -1200,7 +1174,7 @@ RegisterContextLLDB::WriteRegisterBytes (uint32_t lldb_reg, DataExtractor &data, RegisterLocation regloc; // Find out where the NEXT frame saved THIS frame's register contents - if (!((RegisterContextLLDB*)m_next_frame.get())->SavedLocationForRegister (lldb_reg, regloc)) + if (!m_next_frame->SavedLocationForRegister (lldb_reg, regloc)) return false; return WriteRegisterBytesToRegisterLocation (lldb_reg, regloc, data, data_offset); diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h index ba0e05220591..f75a9b84fc56 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h @@ -20,8 +20,10 @@ class RegisterContextLLDB : public lldb_private::RegisterContext { public: + typedef lldb::SharedPtr::Type SharedPtr; + RegisterContextLLDB (lldb_private::Thread &thread, - const lldb::RegisterContextSP& next_frame, + const SharedPtr& next_frame, lldb_private::SymbolContext& sym_ctx, uint32_t frame_number); @@ -147,22 +149,23 @@ private: bool ReadGPRValue (int register_kind, uint32_t regnum, lldb::addr_t &value); - lldb_private::UnwindPlan * + lldb::UnwindPlanSP GetFastUnwindPlanForFrame (); - lldb_private::UnwindPlan * + lldb::UnwindPlanSP GetFullUnwindPlanForFrame (); lldb_private::Thread& m_thread; - lldb::RegisterContextSP m_next_frame; + + SharedPtr m_next_frame; /// // The following tell us how to retrieve the CALLER's register values (ie the "previous" frame, aka the frame above) // i.e. where THIS frame saved them /// - lldb_private::UnwindPlan *m_fast_unwind_plan; // may be NULL - lldb_private::UnwindPlan *m_full_unwind_plan; + lldb::UnwindPlanSP m_fast_unwind_plan_sp; // may be NULL + lldb::UnwindPlanSP m_full_unwind_plan_sp; bool m_all_registers_available; // Can we retrieve all regs or just nonvolatile regs? int m_frame_type; // enum FrameType diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp index 533c21c6e241..e972c8408e80 100644 --- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp +++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp @@ -15,10 +15,12 @@ #include "lldb/Symbol/FuncUnwinders.h" #include "lldb/Symbol/Function.h" #include "lldb/Utility/ArchDefaultUnwindPlan.h" -#include "UnwindLLDB.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Core/Log.h" +#include "UnwindLLDB.h" +#include "RegisterContextLLDB.h" + using namespace lldb; using namespace lldb_private; @@ -65,8 +67,10 @@ UnwindLLDB::AddFirstFrame () { // First, set up the 0th (initial) frame CursorSP first_cursor_sp(new Cursor ()); - RegisterContextSP no_frame; - std::auto_ptr first_register_ctx_ap (new RegisterContextLLDB(m_thread, no_frame, first_cursor_sp->sctx, 0)); + std::auto_ptr first_register_ctx_ap (new RegisterContextLLDB (m_thread, + RegisterContextLLDB::SharedPtr(), + first_cursor_sp->sctx, + 0)); if (first_register_ctx_ap.get() == NULL) return false; @@ -150,8 +154,8 @@ UnwindLLDB::AddOneMoreFrame () return false; } } - RegisterContextSP register_ctx_sp(register_ctx_ap.release()); - cursor_sp->reg_ctx = register_ctx_sp; + RegisterContextLLDB::SharedPtr reg_ctx_sp(register_ctx_ap.release()); + cursor_sp->reg_ctx = reg_ctx_sp; m_frames.push_back (cursor_sp); return true; } diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h index 7d1f070305a1..1c01a3dbc74a 100644 --- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h +++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h @@ -10,15 +10,15 @@ #ifndef lldb_UnwindLLDB_h_ #define lldb_UnwindLLDB_h_ -#include "lldb/lldb-private.h" -#include "lldb/lldb-types.h" -#include "lldb/Target/Unwind.h" +#include + +#include "lldb/lldb-include.h" #include "lldb/Symbol/FuncUnwinders.h" #include "lldb/Symbol/UnwindPlan.h" -#include "RegisterContextLLDB.h" #include "lldb/Target/RegisterContext.h" -#include +#include "lldb/Target/Unwind.h" +#include "RegisterContextLLDB.h" namespace lldb_private { @@ -53,7 +53,7 @@ private: lldb::addr_t start_pc; // The start address of the function/symbol for this frame - current pc if unknown lldb::addr_t cfa; // The canonical frame address for this stack frame lldb_private::SymbolContext sctx; // A symbol context we'll contribute to & provide to the StackFrame creation - lldb::RegisterContextSP reg_ctx; // These are all RegisterContextLLDB's + RegisterContextLLDB::SharedPtr reg_ctx; // These are all RegisterContextLLDB's Cursor () : start_pc (LLDB_INVALID_ADDRESS), cfa (LLDB_INVALID_ADDRESS), sctx(), reg_ctx() { } private: diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index 0e29f2f368f6..873974f0a1d6 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -178,11 +178,12 @@ GDBRemoteRegisterContext::ReadRegisterValue (uint32_t reg, Scalar &value) return false; } -void +bool GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response) { const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); - assert (reg_info); + if (reg_info == NULL) + return false; // Invalidate if needed InvalidateIfNeeded(false); @@ -200,6 +201,7 @@ GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, StringExtractor // leave it as it was. m_reg_valid[reg] = false; } + return success; } diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h index 72c640ff7a8a..ac6bbe5c95df 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h @@ -228,7 +228,7 @@ public: protected: friend class ThreadGDBRemote; - void + bool PrivateSetRegisterValue (uint32_t reg, StringExtractor &response); void diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 87bc0b9a67f7..cee2d3d1dee2 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -642,7 +642,6 @@ ProcessGDBRemote::DidLaunchOrAttach () StreamString strm; - ; // See if the GDB server supports the qHostInfo information const char *vendor = m_gdb_comm.GetVendorString().AsCString(); const char *os_type = m_gdb_comm.GetOSString().AsCString(); @@ -1176,6 +1175,18 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) case 'T': case 'S': { + if (GetStopID() == 0) + { + // Our first stop, make sure we have a process ID, and also make + // sure we know about our registers + if (GetID() == LLDB_INVALID_PROCESS_ID) + { + lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID (1); + if (pid != LLDB_INVALID_PROCESS_ID) + SetID (pid); + } + BuildDynamicRegisterInfo (true); + } // Stop with signal and thread info const uint8_t signo = stop_packet.GetHexU8(); std::string name; @@ -1209,7 +1220,14 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) { // thread in big endian hex tid = Args::StringToUInt32 (value.c_str(), 0, 16); + Mutex::Locker locker (m_thread_list.GetMutex ()); thread_sp = m_thread_list.FindThreadByID(tid, false); + if (!thread_sp) + { + // Create the thread if we need to + thread_sp.reset (new ThreadGDBRemote (*this, tid)); + m_thread_list.AddThread(thread_sp); + } } else if (name.compare("hexname") == 0) { @@ -1242,7 +1260,15 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) StringExtractor reg_value_extractor; // Swap "value" over into "reg_value_extractor" reg_value_extractor.GetStringRef().swap(value); - static_cast (thread_sp.get())->PrivateSetRegisterValue (reg, reg_value_extractor); + if (!static_cast (thread_sp.get())->PrivateSetRegisterValue (reg, reg_value_extractor)) + { + Host::SetCrashDescriptionWithFormat("Setting thread register '%s' (decoded to %u (0x%x)) with value '%s' for stop packet: '%s'", + name.c_str(), + reg, + reg, + reg_value_extractor.GetStringRef().c_str(), + stop_packet.GetStringRef().c_str()); + } } } } diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index 6acefff3216d..635c00c74389 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -26,7 +26,7 @@ #include "Plugins/Process/Utility/UnwindLLDB.h" #include "Utility/StringExtractorGDBRemote.h" -#ifdef __APPLE__ +#if defined(__APPLE__) #include "UnwindMacOSXFrameBackchain.h" #endif @@ -98,6 +98,7 @@ ThreadGDBRemote::WillResume (StateType resume_state) { case eStateSuspended: case eStateStopped: + // Don't append anything for threads that should stay stopped. break; case eStateRunning: @@ -145,7 +146,7 @@ ThreadGDBRemote::GetUnwinder () { m_unwinder_ap.reset (new UnwindLLDB (*this)); } -#ifdef __APPLE__ +#if defined(__APPLE__) else { m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this)); @@ -207,12 +208,12 @@ ThreadGDBRemote::CreateRegisterContextForFrame (StackFrame *frame) return reg_ctx_sp; } -void +bool ThreadGDBRemote::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response) { GDBRemoteRegisterContext *gdb_reg_ctx = static_cast(GetRegisterContext ().get()); assert (gdb_reg_ctx); - gdb_reg_ctx->PrivateSetRegisterValue (reg, response); + return gdb_reg_ctx->PrivateSetRegisterValue (reg, response); } bool diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h index bf708485d737..c085b6c1485a 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h @@ -105,7 +105,7 @@ protected: virtual bool RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint); - void + bool PrivateSetRegisterValue (uint32_t reg, StringExtractor &response); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 5897dbb67fa2..c4705960facb 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -197,6 +197,14 @@ GetDWARFMachOSegmentName () return g_dwarf_section_name; } +UniqueDWARFASTTypeMap & +SymbolFileDWARF::GetUniqueDWARFASTTypeMap () +{ + if (m_debug_map_symfile) + return m_debug_map_symfile->GetUniqueDWARFASTTypeMap (); + return m_unique_ast_type_map; +} + ClangASTContext & SymbolFileDWARF::GetClangASTContext () { @@ -3172,10 +3180,10 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, UniqueDWARFASTType unique_ast_entry; if (decl.IsValid()) { - if (m_unique_ast_type_map.Find (type_name_const_str, - die, - decl, - unique_ast_entry)) + if (GetUniqueDWARFASTTypeMap().Find (type_name_const_str, + die, + decl, + unique_ast_entry)) { // We have already parsed this type or from another // compile unit. GCC loves to use the "one definition @@ -3273,8 +3281,8 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, unique_ast_entry.m_type_sp = type_sp; unique_ast_entry.m_die = die; unique_ast_entry.m_declaration = decl; - m_unique_ast_type_map.Insert (type_name_const_str, - unique_ast_entry); + GetUniqueDWARFASTTypeMap().Insert (type_name_const_str, + unique_ast_entry); if (die->HasChildren() == false && is_forward_declaration == false) { @@ -3824,14 +3832,6 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, type_sp->SetSymbolContextScope(symbol_context_scope); } -// if (udt_sp.get()) -// { -// if (is_forward_declaration) -// udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition); -// type_sp->SetUserDefinedType(udt_sp); -// } - - //printf ("Adding type to map: 0x%8.8x for %s\n", die->GetOffset(), type_sp->GetName().GetCString()); // We are ready to put this type into the uniqued list up at the module level type_list->Insert (type_sp); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index c97bd1f7c383..f2acbf73923b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -321,6 +321,9 @@ protected: clang::NamespaceDecl * ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die); + UniqueDWARFASTTypeMap & + GetUniqueDWARFASTTypeMap (); + SymbolFileDWARFDebugMap * m_debug_map_symfile; clang::TranslationUnitDecl * m_clang_tu_decl; lldb_private::Flags m_flags; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h index 903fc5796c4e..742fb0697e2e 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -15,6 +15,8 @@ #include #include "lldb/Symbol/SymbolFile.h" +#include "UniqueDWARFASTType.h" + class SymbolFileDWARF; class DWARFCompileUnit; class DWARFDebugInfoEntry; @@ -211,6 +213,11 @@ protected: const DWARFDebugInfoEntry *die, const lldb_private::ConstString &type_name); + UniqueDWARFASTTypeMap & + GetUniqueDWARFASTTypeMap () + { + return m_unique_ast_type_map; + } //------------------------------------------------------------------ // Member Variables //------------------------------------------------------------------ @@ -218,6 +225,7 @@ protected: std::vector m_compile_unit_infos; std::vector m_func_indexes; // Sorted by address std::vector m_glob_indexes; + UniqueDWARFASTTypeMap m_unique_ast_type_map; }; #endif // #ifndef liblldb_SymbolFileDWARFDebugMap_h_ diff --git a/lldb/source/Symbol/FuncUnwinders.cpp b/lldb/source/Symbol/FuncUnwinders.cpp index e09ad9201347..71292dbd3d02 100644 --- a/lldb/source/Symbol/FuncUnwinders.cpp +++ b/lldb/source/Symbol/FuncUnwinders.cpp @@ -34,10 +34,10 @@ FuncUnwinders::FuncUnwinders m_assembly_profiler(assembly_profiler), m_range(range), m_mutex (Mutex::eMutexTypeNormal), - m_unwind_at_call_site_ap (), - m_unwind_at_non_call_site_ap (), - m_unwind_fast_ap (), - m_unwind_arch_default (NULL), + m_unwind_plan_call_site_sp (), + m_unwind_plan_non_call_site_sp (), + m_unwind_plan_fast_sp (), + m_unwind_plan_arch_default_sp (), m_tried_unwind_at_call_site (false), m_tried_unwind_at_non_call_site (false), m_tried_unwind_fast (false), @@ -50,15 +50,15 @@ FuncUnwinders::~FuncUnwinders () { } -UnwindPlan* +UnwindPlanSP FuncUnwinders::GetUnwindPlanAtCallSite (int current_offset) { // Lock the mutex to ensure we can always give out the most appropriate // information. We want to make sure if someone requests a call site unwind // plan, that they get one and don't run into a race condition where one // thread has started to create the unwind plan and has put it into - // m_unwind_at_call_site_ap, and have another thread enter this function - // and return the partially filled in m_unwind_at_call_site_ap pointer. + // m_unwind_plan_call_site_sp, and have another thread enter this function + // and return the partially filled in m_unwind_plan_call_site_sp pointer. // We also want to make sure that we lock out other unwind plans from // being accessed until this one is done creating itself in case someone // had some code like: @@ -66,7 +66,7 @@ FuncUnwinders::GetUnwindPlanAtCallSite (int current_offset) // if (best_unwind_plan == NULL) // best_unwind_plan = GetUnwindPlanAtNonCallSite (...) Mutex::Locker locker (m_mutex); - if (m_tried_unwind_at_call_site == false && m_unwind_at_call_site_ap.get() == NULL) + if (m_tried_unwind_at_call_site == false && m_unwind_plan_call_site_sp.get() == NULL) { m_tried_unwind_at_call_site = true; // We have cases (e.g. with _sigtramp on Mac OS X) where the hand-written eh_frame unwind info for a @@ -84,16 +84,16 @@ FuncUnwinders::GetUnwindPlanAtCallSite (int current_offset) DWARFCallFrameInfo *eh_frame = m_unwind_table.GetEHFrameInfo(); if (eh_frame) { - m_unwind_at_call_site_ap.reset (new UnwindPlan); - if (!eh_frame->GetUnwindPlan (current_pc, *m_unwind_at_call_site_ap)) - m_unwind_at_call_site_ap.reset(); + m_unwind_plan_call_site_sp.reset (new UnwindPlan); + if (!eh_frame->GetUnwindPlan (current_pc, *m_unwind_plan_call_site_sp)) + m_unwind_plan_call_site_sp.reset(); } } } - return m_unwind_at_call_site_ap.get(); + return m_unwind_plan_call_site_sp; } -UnwindPlan* +UnwindPlanSP FuncUnwinders::GetUnwindPlanAtNonCallSite (Thread& thread) { // Lock the mutex to ensure we can always give out the most appropriate @@ -109,17 +109,17 @@ FuncUnwinders::GetUnwindPlanAtNonCallSite (Thread& thread) // if (best_unwind_plan == NULL) // best_unwind_plan = GetUnwindPlanAtNonCallSite (...) Mutex::Locker locker (m_mutex); - if (m_tried_unwind_at_non_call_site == false && m_unwind_at_non_call_site_ap.get() == NULL) + if (m_tried_unwind_at_non_call_site == false && m_unwind_plan_non_call_site_sp.get() == NULL) { m_tried_unwind_at_non_call_site = true; - m_unwind_at_non_call_site_ap.reset (new UnwindPlan); - if (!m_assembly_profiler->GetNonCallSiteUnwindPlanFromAssembly (m_range, thread, *m_unwind_at_non_call_site_ap)) - m_unwind_at_non_call_site_ap.reset(); + m_unwind_plan_non_call_site_sp.reset (new UnwindPlan); + if (!m_assembly_profiler->GetNonCallSiteUnwindPlanFromAssembly (m_range, thread, *m_unwind_plan_non_call_site_sp)) + m_unwind_plan_non_call_site_sp.reset(); } - return m_unwind_at_non_call_site_ap.get(); + return m_unwind_plan_non_call_site_sp; } -UnwindPlan* +UnwindPlanSP FuncUnwinders::GetUnwindPlanFastUnwind (Thread& thread) { // Lock the mutex to ensure we can always give out the most appropriate @@ -135,17 +135,17 @@ FuncUnwinders::GetUnwindPlanFastUnwind (Thread& thread) // if (best_unwind_plan == NULL) // best_unwind_plan = GetUnwindPlanAtNonCallSite (...) Mutex::Locker locker (m_mutex); - if (m_tried_unwind_fast == false && m_unwind_fast_ap.get() == NULL) + if (m_tried_unwind_fast == false && m_unwind_plan_fast_sp.get() == NULL) { m_tried_unwind_fast = true; - m_unwind_fast_ap.reset (new UnwindPlan); - if (!m_assembly_profiler->GetFastUnwindPlan (m_range, thread, *m_unwind_fast_ap)) - m_unwind_fast_ap.reset(); + m_unwind_plan_fast_sp.reset (new UnwindPlan); + if (!m_assembly_profiler->GetFastUnwindPlan (m_range, thread, *m_unwind_plan_fast_sp)) + m_unwind_plan_fast_sp.reset(); } - return m_unwind_fast_ap.get(); + return m_unwind_plan_fast_sp; } -UnwindPlan* +UnwindPlanSP FuncUnwinders::GetUnwindPlanArchitectureDefault (Thread& thread) { // Lock the mutex to ensure we can always give out the most appropriate @@ -161,21 +161,20 @@ FuncUnwinders::GetUnwindPlanArchitectureDefault (Thread& thread) // if (best_unwind_plan == NULL) // best_unwind_plan = GetUnwindPlanAtNonCallSite (...) Mutex::Locker locker (m_mutex); - if (m_tried_unwind_arch_default == false && m_unwind_arch_default == NULL) + if (m_tried_unwind_arch_default == false && m_unwind_plan_arch_default_sp.get() == NULL) { m_tried_unwind_arch_default = true; Address current_pc; Target *target = thread.CalculateTarget(); if (target) { - ArchSpec arch = target->GetArchitecture (); - ArchDefaultUnwindPlan *arch_default = ArchDefaultUnwindPlan::FindPlugin (arch); - if (arch_default) - m_unwind_arch_default = arch_default->GetArchDefaultUnwindPlan (thread, current_pc); + ArchDefaultUnwindPlanSP arch_default_sp (ArchDefaultUnwindPlan::FindPlugin (target->GetArchitecture ())); + if (arch_default_sp) + m_unwind_plan_arch_default_sp = arch_default_sp->GetArchDefaultUnwindPlan (thread, current_pc); } } - return m_unwind_arch_default; + return m_unwind_plan_arch_default_sp; } Address& diff --git a/lldb/source/Utility/ArchDefaultUnwindPlan.cpp b/lldb/source/Utility/ArchDefaultUnwindPlan.cpp index 1d5b5b901d02..4b202e15f0ec 100644 --- a/lldb/source/Utility/ArchDefaultUnwindPlan.cpp +++ b/lldb/source/Utility/ArchDefaultUnwindPlan.cpp @@ -7,28 +7,42 @@ // //===----------------------------------------------------------------------===// -#include "lldb/lldb-private.h" #include "lldb/Core/PluginManager.h" + +#include + +#include "lldb/Core/ArchSpec.h" #include "lldb/Core/PluginInterface.h" +#include "lldb/Host/Mutex.h" #include "lldb/Utility/ArchDefaultUnwindPlan.h" using namespace lldb; using namespace lldb_private; -ArchDefaultUnwindPlan* +ArchDefaultUnwindPlanSP ArchDefaultUnwindPlan::FindPlugin (const ArchSpec &arch) { ArchDefaultUnwindPlanCreateInstance create_callback; + typedef std::map ArchDefaultUnwindPlanMap; + static ArchDefaultUnwindPlanMap g_plugin_map; + static Mutex g_plugin_map_mutex (Mutex::eMutexTypeRecursive); + Mutex::Locker locker (g_plugin_map_mutex); + ArchDefaultUnwindPlanMap::iterator pos = g_plugin_map.find (arch); + if (pos != g_plugin_map.end()) + return pos->second; for (uint32_t idx = 0; (create_callback = PluginManager::GetArchDefaultUnwindPlanCreateCallbackAtIndex(idx)) != NULL; ++idx) { - std::auto_ptr default_unwind_plan_ap (create_callback (arch)); - if (default_unwind_plan_ap.get ()) - return default_unwind_plan_ap.release (); + ArchDefaultUnwindPlanSP default_unwind_plan_sp (create_callback (arch)); + if (default_unwind_plan_sp) + { + g_plugin_map[arch] = default_unwind_plan_sp; + return default_unwind_plan_sp; + } } - return NULL; + return ArchDefaultUnwindPlanSP(); } ArchDefaultUnwindPlan::ArchDefaultUnwindPlan () diff --git a/lldb/source/lldb.cpp b/lldb/source/lldb.cpp index 83acbd0d663d..5ea30e01fb34 100644 --- a/lldb/source/lldb.cpp +++ b/lldb/source/lldb.cpp @@ -76,7 +76,8 @@ lldb_private::Initialize () SymbolFileDWARF::Initialize(); SymbolFileSymtab::Initialize(); UnwindAssemblyProfiler_x86::Initialize(); - ArchDefaultUnwindPlan_x86::Initialize(); + ArchDefaultUnwindPlan_x86_64::Initialize(); + ArchDefaultUnwindPlan_i386::Initialize(); ArchVolatileRegs_x86::Initialize(); ScriptInterpreter::Initialize (); @@ -123,7 +124,8 @@ lldb_private::Terminate () SymbolFileDWARF::Terminate(); SymbolFileSymtab::Terminate(); UnwindAssemblyProfiler_x86::Terminate(); - ArchDefaultUnwindPlan_x86::Terminate(); + ArchDefaultUnwindPlan_i386::Terminate(); + ArchDefaultUnwindPlan_x86_64::Terminate(); ArchVolatileRegs_x86::Terminate(); ScriptInterpreter::Terminate (); -- GitLab