diff options
14 files changed, 217 insertions, 106 deletions
diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolver.h b/lldb/include/lldb/Breakpoint/BreakpointResolver.h index b05b8c57299..7cbbbe34da0 100644 --- a/lldb/include/lldb/Breakpoint/BreakpointResolver.h +++ b/lldb/include/lldb/Breakpoint/BreakpointResolver.h @@ -121,7 +121,8 @@ public: FileLineResolver, // This is an instance of BreakpointResolverFileLine AddressResolver, // This is an instance of BreakpointResolverAddress NameResolver, // This is an instance of BreakpointResolverName - FileRegexResolver + FileRegexResolver, + ExceptionResolver }; //------------------------------------------------------------------ diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverName.h b/lldb/include/lldb/Breakpoint/BreakpointResolverName.h index 2732f478279..6804b9c226f 100644 --- a/lldb/include/lldb/Breakpoint/BreakpointResolverName.h +++ b/lldb/include/lldb/Breakpoint/BreakpointResolverName.h @@ -35,6 +35,13 @@ public: Breakpoint::MatchType type, bool skip_prologue); + // This one takes an array of names. It is always MatchType = Name. + BreakpointResolverName (Breakpoint *bkpt, + const char *names[], + size_t num_names, + uint32_t name_type_mask, + bool skip_prologue); + // Creates a function breakpoint by regular expression. Takes over control of the lifespan of func_regex. BreakpointResolverName (Breakpoint *bkpt, RegularExpression &func_regex, @@ -71,7 +78,7 @@ public: } protected: - ConstString m_func_name; + std::vector<ConstString> m_func_names; uint32_t m_func_name_type_mask; // See FunctionNameType ConstString m_class_name; // FIXME: Not used yet. The idea would be to stop on methods of this class. RegularExpression m_regex; diff --git a/lldb/include/lldb/Target/LanguageRuntime.h b/lldb/include/lldb/Target/LanguageRuntime.h index e6c4fe3a0bd..90073d886c1 100644 --- a/lldb/include/lldb/Target/LanguageRuntime.h +++ b/lldb/include/lldb/Target/LanguageRuntime.h @@ -15,6 +15,7 @@ // Other libraries and framework includes // Project includes #include "lldb/lldb-public.h" +#include "lldb/Breakpoint/BreakpointResolver.h" #include "lldb/Core/PluginInterface.h" #include "lldb/lldb-private.h" #include "lldb/Core/ValueObject.h" @@ -68,10 +69,18 @@ public: { return false; } + protected: //------------------------------------------------------------------ // Classes that inherit from LanguageRuntime can see and modify these //------------------------------------------------------------------ + + // The Target is the one that knows how to create breakpoints, so this function is meant to be used either + // by the target or internally in Set/ClearExceptionBreakpoints. + + virtual lldb::BreakpointSP + CreateExceptionBreakpoint (bool catch_bp, bool throw_bp, bool is_internal = false) = 0; + LanguageRuntime(Process *process); Process *m_process; private: diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 092941887c3..a2834659a2e 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -468,6 +468,19 @@ public: uint32_t func_name_type_mask, bool internal = false, LazyBool skip_prologue = eLazyBoolCalculate); + + // This is the same as the func_name breakpoint except that you can specify a vector of names. This is cheaper + // than a regular expression breakpoint in the case where you just want to set a breakpoint on a set of names + // you already know. + lldb::BreakpointSP + CreateBreakpoint (const FileSpecList *containingModules, + const FileSpecList *containingSourceFiles, + const char *func_names[], + size_t num_names, + uint32_t func_name_type_mask, + bool internal = false, + LazyBool skip_prologue = eLazyBoolCalculate); + // Use this to create a general breakpoint: lldb::BreakpointSP diff --git a/lldb/source/Breakpoint/BreakpointResolverName.cpp b/lldb/source/Breakpoint/BreakpointResolverName.cpp index 9b958c4066f..7b7e7a4f8d0 100644 --- a/lldb/source/Breakpoint/BreakpointResolverName.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverName.cpp @@ -31,24 +31,42 @@ BreakpointResolverName::BreakpointResolverName bool skip_prologue ) : BreakpointResolver (bkpt, BreakpointResolver::NameResolver), - m_func_name (func_name), m_func_name_type_mask (func_name_type_mask), m_class_name (), m_regex (), m_match_type (type), m_skip_prologue (skip_prologue) { - + if (m_match_type == Breakpoint::Regexp) { - if (!m_regex.Compile (m_func_name.AsCString())) + if (!m_regex.Compile (func_name)) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); if (log) - log->Warning ("function name regexp: \"%s\" did not compile.", m_func_name.AsCString()); + log->Warning ("function name regexp: \"%s\" did not compile.", func_name); } } + else + { + m_func_names.push_back(ConstString(func_name)); + } +} + +BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt, + const char *names[], + size_t num_names, + uint32_t name_type_mask, + bool skip_prologue) : + BreakpointResolver (bkpt, BreakpointResolver::NameResolver), + m_func_name_type_mask (name_type_mask), + m_skip_prologue (skip_prologue) +{ + for (size_t i = 0; i < num_names; i++) + { + m_func_names.push_back (ConstString (names[i])); + } } BreakpointResolverName::BreakpointResolverName @@ -58,7 +76,6 @@ BreakpointResolverName::BreakpointResolverName bool skip_prologue ) : BreakpointResolver (bkpt, BreakpointResolver::NameResolver), - m_func_name (NULL), m_class_name (NULL), m_regex (func_regex), m_match_type (Breakpoint::Regexp), @@ -75,13 +92,12 @@ BreakpointResolverName::BreakpointResolverName bool skip_prologue ) : BreakpointResolver (bkpt, BreakpointResolver::NameResolver), - m_func_name (method), m_class_name (class_name), m_regex (), m_match_type (type), m_skip_prologue (skip_prologue) { - + m_func_names.push_back(ConstString(method)); } BreakpointResolverName::~BreakpointResolverName () @@ -121,7 +137,7 @@ BreakpointResolverName::SearchCallback const bool include_symbols = false; const bool include_inlines = true; - const bool append = false; + const bool append = true; bool filter_by_cu = (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0; switch (m_match_type) @@ -129,20 +145,24 @@ BreakpointResolverName::SearchCallback case Breakpoint::Exact: if (context.module_sp) { - uint32_t num_functions = context.module_sp->FindFunctions (m_func_name, - NULL, - m_func_name_type_mask, - include_symbols, - include_inlines, - append, - func_list); - // If the search filter specifies a Compilation Unit, then we don't need to bother to look in plain - // symbols, since all the ones from a set compilation unit will have been found above already. - - if (num_functions == 0 && !filter_by_cu) + size_t num_names = m_func_names.size(); + for (int i = 0; i < num_names; i++) { - if (m_func_name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeAuto)) - context.module_sp->FindSymbolsWithNameAndType (m_func_name, eSymbolTypeCode, sym_list); + uint32_t num_functions = context.module_sp->FindFunctions (m_func_names[i], + NULL, + m_func_name_type_mask, + include_symbols, + include_inlines, + append, + func_list); + // If the search filter specifies a Compilation Unit, then we don't need to bother to look in plain + // symbols, since all the ones from a set compilation unit will have been found above already. + + if (num_functions == 0 && !filter_by_cu) + { + if (m_func_name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeAuto)) + context.module_sp->FindSymbolsWithNameAndType (m_func_names[i], eSymbolTypeCode, sym_list); + } } } break; @@ -299,7 +319,20 @@ BreakpointResolverName::GetDescription (Stream *s) if (m_match_type == Breakpoint::Regexp) s->Printf("regex = '%s'", m_regex.GetText()); else - s->Printf("name = '%s'", m_func_name.AsCString()); + { + size_t num_names = m_func_names.size(); + if (num_names == 1) + s->Printf("name = '%s'", m_func_names[0].AsCString()); + else + { + s->Printf("names = {"); + for (size_t i = 0; i < num_names - 1; i++) + { + s->Printf ("'%s', ", m_func_names[i].AsCString()); + } + s->Printf ("'%s'}", m_func_names[num_names - 1].AsCString()); + } + } } void diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp index 9668e9e3a28..ebf2a093fc4 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -209,7 +209,7 @@ ItaniumABILanguageRuntime::IsVTableName (const char *name) //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ -lldb_private::LanguageRuntime * +LanguageRuntime * ItaniumABILanguageRuntime::CreateInstance (Process *process, lldb::LanguageType language) { // FIXME: We have to check the process and make sure we actually know that this process supports @@ -255,29 +255,56 @@ ItaniumABILanguageRuntime::GetPluginVersion() return 1; } +static const char *exception_names[] = {"__cxa_throw", "__cxa_allocate", "__cxa_rethrow", "__cxa_catch"}; +static const int num_throw_names = 3; + +BreakpointSP +ItaniumABILanguageRuntime::CreateExceptionBreakpoint (bool catch_bp, bool throw_bp, bool is_internal) +{ + BreakpointSP exc_breakpt_sp; + if (catch_bp && throw_bp) + exc_breakpt_sp = m_process->GetTarget().CreateBreakpoint (NULL, + NULL, + exception_names, + sizeof (exception_names)/sizeof (char *), + eFunctionNameTypeBase, + is_internal, + eLazyBoolNo); + else if (throw_bp) + exc_breakpt_sp = m_process->GetTarget().CreateBreakpoint (NULL, + NULL, + exception_names, + num_throw_names, + eFunctionNameTypeBase, + is_internal, + eLazyBoolNo); + else if (catch_bp) + exc_breakpt_sp = m_process->GetTarget().CreateBreakpoint (NULL, + NULL, + exception_names + num_throw_names, + sizeof (exception_names)/sizeof (char *) - num_throw_names, + eFunctionNameTypeBase, + is_internal, + eLazyBoolNo); + + return exc_breakpt_sp; +} + void ItaniumABILanguageRuntime::SetExceptionBreakpoints () { if (!m_process) return; + const bool catch_bp = false; + const bool throw_bp = true; + const bool is_internal = true; + if (!m_cxx_exception_bp_sp) - m_cxx_exception_bp_sp = m_process->GetTarget().CreateBreakpoint (NULL, - NULL, - "__cxa_throw", - eFunctionNameTypeBase, - true); + m_cxx_exception_bp_sp = CreateExceptionBreakpoint (catch_bp, throw_bp, is_internal); else m_cxx_exception_bp_sp->SetEnabled (true); - if (!m_cxx_exception_alloc_bp_sp) - m_cxx_exception_alloc_bp_sp = m_process->GetTarget().CreateBreakpoint (NULL, - NULL, - "__cxa_allocate", - eFunctionNameTypeBase, - true); - else - m_cxx_exception_alloc_bp_sp->SetEnabled (true); } void @@ -289,12 +316,7 @@ ItaniumABILanguageRuntime::ClearExceptionBreakpoints () if (m_cxx_exception_bp_sp.get()) { m_cxx_exception_bp_sp->SetEnabled (false); - } - - if (m_cxx_exception_alloc_bp_sp.get()) - { - m_cxx_exception_bp_sp->SetEnabled (false); - } + } } bool @@ -315,30 +337,18 @@ ItaniumABILanguageRuntime::ExceptionBreakpointsExplainStop (lldb::StopInfoSP sto uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); - bool check_cxx_exception = false; break_id_t cxx_exception_bid; - bool check_cxx_exception_alloc = false; - break_id_t cxx_exception_alloc_bid; - - if (m_cxx_exception_bp_sp) - { - check_cxx_exception = true; - cxx_exception_bid = m_cxx_exception_bp_sp->GetID(); - } - - if (m_cxx_exception_alloc_bp_sp) - { - check_cxx_exception_alloc = true; - cxx_exception_alloc_bid = m_cxx_exception_alloc_bp_sp->GetID(); - } - + if (!m_cxx_exception_bp_sp) + return false; + + cxx_exception_bid = m_cxx_exception_bp_sp->GetID(); + for (uint32_t i = 0; i < num_owners; i++) { break_id_t bid = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().GetID(); - if ((check_cxx_exception && (bid == cxx_exception_bid)) || - (check_cxx_exception_alloc && (bid == cxx_exception_alloc_bid))) + if (bid == cxx_exception_bid) return true; } diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h index d9d26008761..ae7fa991b2b 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h @@ -15,6 +15,7 @@ // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" +#include "lldb/Breakpoint/BreakpointResolver.h" #include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/CPPLanguageRuntime.h" #include "lldb/Core/Value.h" @@ -73,11 +74,13 @@ namespace lldb_private { ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason); protected: + virtual lldb::BreakpointSP + CreateExceptionBreakpoint (bool catch_bp, bool throw_bp, bool is_internal = false); + private: ItaniumABILanguageRuntime(Process *process) : lldb_private::CPPLanguageRuntime(process) { } // Call CreateInstance instead. lldb::BreakpointSP m_cxx_exception_bp_sp; - lldb::BreakpointSP m_cxx_exception_alloc_bp_sp; }; } // namespace lldb_private diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp index eaae268eb59..8f955f9dc57 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp @@ -288,6 +288,20 @@ AppleObjCRuntime::GetObjCVersion (Process *process, ModuleSP &objc_module_sp) } void +AppleObjCRuntime::SetExceptionBreakpoints () +{ + const bool catch_bp = false; + const bool throw_bp = true; + const bool is_internal = true; + + if (!m_objc_exception_bp_sp) + m_objc_exception_bp_sp = CreateExceptionBreakpoint (catch_bp, throw_bp, is_internal); + else + m_objc_exception_bp_sp->SetEnabled(true); +} + + +void AppleObjCRuntime::ClearExceptionBreakpoints () { if (!m_process) @@ -317,20 +331,18 @@ AppleObjCRuntime::ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason) uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); - bool check_objc_exception = false; break_id_t objc_exception_bid; - if (m_objc_exception_bp_sp) - { - check_objc_exception = true; - objc_exception_bid = m_objc_exception_bp_sp->GetID(); - } + if (!m_objc_exception_bp_sp) + return false; + + objc_exception_bid = m_objc_exception_bp_sp->GetID(); for (uint32_t i = 0; i < num_owners; i++) { break_id_t bid = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().GetID(); - if ((check_objc_exception && (bid == objc_exception_bid))) + if (bid == objc_exception_bid) return true; } diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h index 4f2b70e4fd4..bda16e28277 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h @@ -104,6 +104,8 @@ protected: // PluginInterface protocol //------------------------------------------------------------------ public: + virtual void + SetExceptionBreakpoints(); virtual void ClearExceptionBreakpoints (); diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp index f02b23d4417..7f3e8dfad2e 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp @@ -104,22 +104,22 @@ AppleObjCRuntimeV1::GetPluginVersion() return 1; } -void -AppleObjCRuntimeV1::SetExceptionBreakpoints () +BreakpointSP +AppleObjCRuntimeV1::CreateExceptionBreakpoint (bool catch_bp, bool throw_bp, bool is_internal) { + BreakpointSP exc_breakpt_sp; if (!m_process) - return; - - if (!m_objc_exception_bp_sp) - { - m_objc_exception_bp_sp = m_process->GetTarget().CreateBreakpoint (NULL, - NULL, - "objc_exception_throw", - eFunctionNameTypeBase, - true); - } - else - m_objc_exception_bp_sp->SetEnabled (true); + return exc_breakpt_sp; + + + // FIXME: Only do throw for now... + if (throw_bp) + exc_breakpt_sp = m_process->GetTarget().CreateBreakpoint (NULL, + NULL, + "objc_exception_throw", + eFunctionNameTypeBase, + is_internal); + return exc_breakpt_sp; } struct BufStruct { diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h index 1f2ace45f2d..38a36f189a4 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h @@ -60,9 +60,6 @@ public: virtual uint32_t GetPluginVersion(); - virtual void - SetExceptionBreakpoints (); - virtual ObjCRuntimeVersions GetRuntimeVersion () { @@ -94,7 +91,9 @@ public: } protected: - + virtual lldb::BreakpointSP + CreateExceptionBreakpoint (bool catch_bp, bool throw_bp, bool is_internal = false); + private: AppleObjCRuntimeV1(Process *process) : lldb_private::AppleObjCRuntime (process) diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index 98ef4ada95b..ff6241491d7 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -444,22 +444,22 @@ AppleObjCRuntimeV2::GetPluginVersion() return 1; } -void -AppleObjCRuntimeV2::SetExceptionBreakpoints () +BreakpointSP +AppleObjCRuntimeV2::CreateExceptionBreakpoint (bool catch_bp, bool throw_bp, bool is_internal) { + BreakpointSP exc_breakpt_sp; if (!m_process) - return; - - if (!m_objc_exception_bp_sp) - { - m_objc_exception_bp_sp = m_process->GetTarget().CreateBreakpoint (NULL, - NULL, - "__cxa_throw", - eFunctionNameTypeBase, - true); - } - else - m_objc_exception_bp_sp->SetEnabled (true); + return exc_breakpt_sp; + + + // FIXME: Only do throw for now... + if (throw_bp) + exc_breakpt_sp = m_process->GetTarget().CreateBreakpoint (NULL, + NULL, + "objc_exception_throw", + eFunctionNameTypeBase, + is_internal); + return exc_breakpt_sp; } ClangUtilityFunction * diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h index f53dc59b04a..47a1f40d77d 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h @@ -64,9 +64,6 @@ public: virtual uint32_t GetPluginVersion(); - virtual void - SetExceptionBreakpoints (); - virtual ObjCRuntimeVersions GetRuntimeVersion () { @@ -100,7 +97,9 @@ public: GetSymbolVendor(); protected: - + virtual lldb::BreakpointSP + CreateExceptionBreakpoint (bool catch_bp, bool throw_bp, bool is_internal = false); + private: typedef std::map<ObjCLanguageRuntime::ObjCISA, ConstString> ISAToNameCache; diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 9b171d7b72d..01fb9747db9 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -287,6 +287,29 @@ Target::CreateBreakpoint (const FileSpecList *containingModules, return bp_sp; } +BreakpointSP +Target::CreateBreakpoint (const FileSpecList *containingModules, + const FileSpecList *containingSourceFiles, + const char *func_names[], + size_t num_names, + uint32_t func_name_type_mask, + bool internal, + LazyBool skip_prologue) +{ + BreakpointSP bp_sp; + if (num_names > 0) + { + SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, containingSourceFiles)); + + BreakpointResolverSP resolver_sp (new BreakpointResolverName (NULL, + func_names, + num_names, + func_name_type_mask, + skip_prologue == eLazyBoolCalculate ? GetSkipPrologue() : skip_prologue)); + bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal); + } + return bp_sp; +} SearchFilterSP Target::GetSearchFilterForModule (const FileSpec *containingModule) |

