Index: include/lldb/Core/PluginManager.h =================================================================== --- include/lldb/Core/PluginManager.h +++ include/lldb/Core/PluginManager.h @@ -134,10 +134,11 @@ GetLanguageCreateCallbackForPluginName(ConstString name); // LanguageRuntime - static bool - RegisterPlugin(ConstString name, const char *description, - LanguageRuntimeCreateInstance create_callback, - LanguageRuntimeGetCommandObject command_callback = nullptr); + static bool RegisterPlugin( + ConstString name, const char *description, + LanguageRuntimeCreateInstance create_callback, + LanguageRuntimeGetCommandObject command_callback = nullptr, + LanguageRuntimeAddBreakpointPrecondition precondition_callback = nullptr); static bool UnregisterPlugin(LanguageRuntimeCreateInstance create_callback); @@ -147,6 +148,9 @@ static LanguageRuntimeGetCommandObject GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx); + static LanguageRuntimeAddBreakpointPrecondition + GetLanguageRuntimeAddBreakpointPreconditionAtIndex(uint32_t idx); + static LanguageRuntimeCreateInstance GetLanguageRuntimeCreateCallbackForPluginName(ConstString name); Index: include/lldb/Target/LanguageRuntime.h =================================================================== --- include/lldb/Target/LanguageRuntime.h +++ include/lldb/Target/LanguageRuntime.h @@ -115,9 +115,9 @@ bool catch_bp, bool throw_bp, bool is_internal = false); - static Breakpoint::BreakpointPreconditionSP - CreateExceptionPrecondition(lldb::LanguageType language, bool catch_bp, - bool throw_bp); + static void AddExceptionPrecondition(lldb::BreakpointSP breakpoint, + lldb::LanguageType language, + bool throw_bp); virtual lldb::ValueObjectSP GetExceptionObjectForThread( lldb::ThreadSP thread_sp) { Index: include/lldb/Target/ObjCLanguageRuntime.h =================================================================== --- include/lldb/Target/ObjCLanguageRuntime.h +++ include/lldb/Target/ObjCLanguageRuntime.h @@ -171,6 +171,10 @@ std::unordered_set m_class_names; }; + static void SetBreakpointExceptionPrecondition(lldb::BreakpointSP breakpoint, + lldb::LanguageType language, + bool throw_bp); + class TaggedPointerVendor { public: virtual ~TaggedPointerVendor() = default; Index: include/lldb/lldb-private-interfaces.h =================================================================== --- include/lldb/lldb-private-interfaces.h +++ include/lldb/lldb-private-interfaces.h @@ -55,6 +55,8 @@ Process *process, lldb::LanguageType language); typedef lldb::CommandObjectSP (*LanguageRuntimeGetCommandObject)( CommandInterpreter &interpreter); +typedef void (*LanguageRuntimeAddBreakpointPrecondition)( + lldb::BreakpointSP breakpoint, lldb::LanguageType language, bool throw_bp); typedef lldb::StructuredDataPluginSP (*StructuredDataPluginCreateInstance)( Process &process); typedef Status (*StructuredDataFilterLaunchInfo)(ProcessLaunchInfo &launch_info, Index: source/Core/PluginManager.cpp =================================================================== --- source/Core/PluginManager.cpp +++ source/Core/PluginManager.cpp @@ -828,6 +828,7 @@ std::string description; LanguageRuntimeCreateInstance create_callback; LanguageRuntimeGetCommandObject command_callback; + LanguageRuntimeAddBreakpointPrecondition precondition_callback; }; typedef std::vector LanguageRuntimeInstances; @@ -845,7 +846,8 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, LanguageRuntimeCreateInstance create_callback, - LanguageRuntimeGetCommandObject command_callback) { + LanguageRuntimeGetCommandObject command_callback, + LanguageRuntimeAddBreakpointPrecondition precondition_callback) { if (create_callback) { LanguageRuntimeInstance instance; assert((bool)name); @@ -854,6 +856,7 @@ instance.description = description; instance.create_callback = create_callback; instance.command_callback = command_callback; + instance.precondition_callback = precondition_callback; std::lock_guard guard(GetLanguageRuntimeMutex()); GetLanguageRuntimeInstances().push_back(instance); } @@ -895,6 +898,15 @@ return nullptr; } +LanguageRuntimeAddBreakpointPrecondition +PluginManager::GetLanguageRuntimeAddBreakpointPreconditionAtIndex(uint32_t idx) { + std::lock_guard guard(GetLanguageRuntimeMutex()); + LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); + if (idx < instances.size()) + return instances[idx].precondition_callback; + return nullptr; +} + LanguageRuntimeCreateInstance PluginManager::GetLanguageRuntimeCreateCallbackForPluginName( ConstString name) { Index: source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp =================================================================== --- source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp +++ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp @@ -85,7 +85,9 @@ void AppleObjCRuntimeV1::Initialize() { PluginManager::RegisterPlugin( GetPluginNameStatic(), "Apple Objective-C Language Runtime - Version 1", - CreateInstance); + CreateInstance, + /*command_callback = */ nullptr, + ObjCLanguageRuntime::SetBreakpointExceptionPrecondition); } void AppleObjCRuntimeV1::Terminate() { Index: source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp =================================================================== --- source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -806,7 +806,8 @@ CreateInstance, [](CommandInterpreter &interpreter) -> lldb::CommandObjectSP { return CommandObjectSP(new CommandObjectMultiwordObjC(interpreter)); - }); + }, + ObjCLanguageRuntime::SetBreakpointExceptionPrecondition); } void AppleObjCRuntimeV2::Terminate() { Index: source/Target/LanguageRuntime.cpp =================================================================== --- source/Target/LanguageRuntime.cpp +++ source/Target/LanguageRuntime.cpp @@ -11,7 +11,6 @@ #include "lldb/Core/SearchFilter.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Target/Language.h" -#include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Target.h" using namespace lldb; @@ -224,19 +223,23 @@ LanguageRuntime::~LanguageRuntime() = default; -Breakpoint::BreakpointPreconditionSP -LanguageRuntime::CreateExceptionPrecondition(lldb::LanguageType language, - bool catch_bp, bool throw_bp) { - switch (language) { - case eLanguageTypeObjC: - if (throw_bp) - return Breakpoint::BreakpointPreconditionSP( - new ObjCLanguageRuntime::ObjCExceptionPrecondition()); - break; - default: - break; +void LanguageRuntime::AddExceptionPrecondition(BreakpointSP breakpoint, + LanguageType language, + bool throw_bp) { + LanguageRuntimeCreateInstance create_callback; + for (uint32_t idx = 0; + (create_callback = + PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != + nullptr; + idx++) { + if (auto precondition_callback = + PluginManager::GetLanguageRuntimeAddBreakpointPreconditionAtIndex( + idx)) { + precondition_callback(breakpoint, language, throw_bp); + if (breakpoint->GetPrecondition()) + break; + } } - return Breakpoint::BreakpointPreconditionSP(); } BreakpointSP LanguageRuntime::CreateExceptionBreakpoint( @@ -252,10 +255,7 @@ target.CreateBreakpoint(filter_sp, resolver_sp, is_internal, hardware, resolve_indirect_functions)); if (exc_breakpt_sp) { - Breakpoint::BreakpointPreconditionSP precondition_sp = - CreateExceptionPrecondition(language, catch_bp, throw_bp); - if (precondition_sp) - exc_breakpt_sp->SetPrecondition(precondition_sp); + AddExceptionPrecondition(exc_breakpt_sp, language, throw_bp); if (is_internal) exc_breakpt_sp->SetBreakpointKind("exception"); Index: source/Target/ObjCLanguageRuntime.cpp =================================================================== --- source/Target/ObjCLanguageRuntime.cpp +++ source/Target/ObjCLanguageRuntime.cpp @@ -375,6 +375,17 @@ return found; } +void ObjCLanguageRuntime::SetBreakpointExceptionPrecondition( + BreakpointSP breakpoint, LanguageType language, bool throw_bp) { + if (!throw_bp) + return; + Breakpoint::BreakpointPreconditionSP precondition_sp( + new ObjCLanguageRuntime::ObjCExceptionPrecondition()); + if (!precondition_sp) + return; + breakpoint->SetPrecondition(precondition_sp); +} + // Exception breakpoint Precondition class for ObjC: void ObjCLanguageRuntime::ObjCExceptionPrecondition::AddClassName( const char *class_name) {