summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Langford <apl@fb.com>2019-06-21 19:43:07 +0000
committerAlex Langford <apl@fb.com>2019-06-21 19:43:07 +0000
commitcde4416d690b418a800dfcbfe24913348687af6a (patch)
tree2faa5a88f241e97b8f99f5679877db656f8dc6c2
parentf74b3d086c37a7c04338338930f14a227bd6d5a7 (diff)
[Target] Decouple ObjCLanguageRuntime from LanguageRuntime
Summary: ObjCLanguageRuntime was being pulled into LanguageRuntime because of Breakpoint Preconditions. If we move BreakpointPrecondition out of Breakpoint, we can extend the LanguageRuntime plugin interface so that LanguageRuntimes can give us a BreakpointPrecondition for exceptions. Differential Revision: https://reviews.llvm.org/D63181 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@364098 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/lldb/Breakpoint/Breakpoint.h25
-rw-r--r--include/lldb/Breakpoint/BreakpointPrecondition.h30
-rw-r--r--include/lldb/Core/PluginManager.h12
-rw-r--r--include/lldb/Target/LanguageRuntime.h5
-rw-r--r--include/lldb/Target/ObjCLanguageRuntime.h7
-rw-r--r--include/lldb/lldb-forward.h2
-rw-r--r--include/lldb/lldb-private-interfaces.h3
-rw-r--r--source/Breakpoint/Breakpoint.cpp16
-rw-r--r--source/Breakpoint/BreakpointPrecondition.cpp26
-rw-r--r--source/Breakpoint/CMakeLists.txt1
-rw-r--r--source/Core/PluginManager.cpp14
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp3
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp3
-rw-r--r--source/Target/LanguageRuntime.cpp37
-rw-r--r--source/Target/ObjCLanguageRuntime.cpp12
-rw-r--r--source/Target/Target.cpp4
16 files changed, 135 insertions, 65 deletions
diff --git a/include/lldb/Breakpoint/Breakpoint.h b/include/lldb/Breakpoint/Breakpoint.h
index 7e25d9ff9..f561b6d90 100644
--- a/include/lldb/Breakpoint/Breakpoint.h
+++ b/include/lldb/Breakpoint/Breakpoint.h
@@ -140,19 +140,6 @@ public:
DISALLOW_COPY_AND_ASSIGN(BreakpointEventData);
};
- class BreakpointPrecondition {
- public:
- virtual ~BreakpointPrecondition() = default;
-
- virtual bool EvaluatePrecondition(StoppointCallbackContext &context);
-
- virtual Status ConfigurePrecondition(Args &options);
-
- virtual void GetDescription(Stream &stream, lldb::DescriptionLevel level);
- };
-
- typedef std::shared_ptr<BreakpointPrecondition> BreakpointPreconditionSP;
-
// Saving & restoring breakpoints:
static lldb::BreakpointSP CreateFromStructuredData(
Target &target, StructuredData::ObjectSP &data_object_sp, Status &error);
@@ -558,14 +545,14 @@ public:
/// The Precondition should not continue the target, it should return true
/// if the condition says to stop and false otherwise.
///
- void SetPrecondition(BreakpointPreconditionSP precondition_sp) {
+ void SetPrecondition(lldb::BreakpointPreconditionSP precondition_sp) {
m_precondition_sp = precondition_sp;
}
bool EvaluatePrecondition(StoppointCallbackContext &context);
- BreakpointPreconditionSP GetPrecondition() { return m_precondition_sp; }
-
+ lldb::BreakpointPreconditionSP GetPrecondition() { return m_precondition_sp; }
+
// Produces the OR'ed values for all the names assigned to this breakpoint.
const BreakpointName::Permissions &GetPermissions() const {
return m_permissions;
@@ -659,9 +646,9 @@ private:
m_filter_sp; // The filter that constrains the breakpoint's domain.
lldb::BreakpointResolverSP
m_resolver_sp; // The resolver that defines this breakpoint.
- BreakpointPreconditionSP m_precondition_sp; // The precondition is a
- // breakpoint-level hit filter
- // that can be used
+ lldb::BreakpointPreconditionSP m_precondition_sp; // The precondition is a
+ // breakpoint-level hit
+ // filter that can be used
// to skip certain breakpoint hits. For instance, exception breakpoints use
// this to limit the stop to certain exception classes, while leaving the
// condition & callback free for user specification.
diff --git a/include/lldb/Breakpoint/BreakpointPrecondition.h b/include/lldb/Breakpoint/BreakpointPrecondition.h
new file mode 100644
index 000000000..2a9461b52
--- /dev/null
+++ b/include/lldb/Breakpoint/BreakpointPrecondition.h
@@ -0,0 +1,30 @@
+//===-- BreakpointPrecondition.h --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_BreakpointPrecondition_h_
+#define liblldb_BreakpointPrecondition_h_
+
+#include "lldb/lldb-enumerations.h"
+
+namespace lldb_private {
+
+class Args;
+class Status;
+class StoppointCallbackContext;
+class Stream;
+
+class BreakpointPrecondition {
+public:
+ virtual ~BreakpointPrecondition() = default;
+ virtual bool EvaluatePrecondition(StoppointCallbackContext &context);
+ virtual Status ConfigurePrecondition(Args &args);
+ virtual void GetDescription(Stream &stream, lldb::DescriptionLevel level);
+};
+} // namespace lldb_private
+
+#endif
diff --git a/include/lldb/Core/PluginManager.h b/include/lldb/Core/PluginManager.h
index b21b5cf14..1bac1e5df 100644
--- a/include/lldb/Core/PluginManager.h
+++ b/include/lldb/Core/PluginManager.h
@@ -134,10 +134,11 @@ public:
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,
+ LanguageRuntimeGetExceptionPrecondition precondition_callback = nullptr);
static bool UnregisterPlugin(LanguageRuntimeCreateInstance create_callback);
@@ -147,6 +148,9 @@ public:
static LanguageRuntimeGetCommandObject
GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx);
+ static LanguageRuntimeGetExceptionPrecondition
+ GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx);
+
static LanguageRuntimeCreateInstance
GetLanguageRuntimeCreateCallbackForPluginName(ConstString name);
diff --git a/include/lldb/Target/LanguageRuntime.h b/include/lldb/Target/LanguageRuntime.h
index 91b3b56d5..e3800616c 100644
--- a/include/lldb/Target/LanguageRuntime.h
+++ b/include/lldb/Target/LanguageRuntime.h
@@ -115,9 +115,8 @@ public:
bool catch_bp, bool throw_bp,
bool is_internal = false);
- static Breakpoint::BreakpointPreconditionSP
- CreateExceptionPrecondition(lldb::LanguageType language, bool catch_bp,
- bool throw_bp);
+ static lldb::BreakpointPreconditionSP
+ GetExceptionPrecondition(lldb::LanguageType language, bool throw_bp);
virtual lldb::ValueObjectSP GetExceptionObjectForThread(
lldb::ThreadSP thread_sp) {
diff --git a/include/lldb/Target/ObjCLanguageRuntime.h b/include/lldb/Target/ObjCLanguageRuntime.h
index 5b5a6cd2b..4875650d9 100644
--- a/include/lldb/Target/ObjCLanguageRuntime.h
+++ b/include/lldb/Target/ObjCLanguageRuntime.h
@@ -16,6 +16,7 @@
#include "llvm/Support/Casting.h"
+#include "lldb/Breakpoint/BreakpointPrecondition.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/ThreadSafeDenseMap.h"
#include "lldb/Symbol/CompilerType.h"
@@ -154,7 +155,7 @@ public:
std::unique_ptr<ClangASTContext> m_scratch_ast_ctx_up;
};
- class ObjCExceptionPrecondition : public Breakpoint::BreakpointPrecondition {
+ class ObjCExceptionPrecondition : public BreakpointPrecondition {
public:
ObjCExceptionPrecondition();
@@ -171,6 +172,10 @@ public:
std::unordered_set<std::string> m_class_names;
};
+ static lldb::BreakpointPreconditionSP
+ GetBreakpointExceptionPrecondition(lldb::LanguageType language,
+ bool throw_bp);
+
class TaggedPointerVendor {
public:
virtual ~TaggedPointerVendor() = default;
diff --git a/include/lldb/lldb-forward.h b/include/lldb/lldb-forward.h
index ccb5f13e1..0cdaf1cf9 100644
--- a/include/lldb/lldb-forward.h
+++ b/include/lldb/lldb-forward.h
@@ -37,6 +37,7 @@ class BreakpointLocationList;
class BreakpointName;
class BreakpointOptionGroup;
class BreakpointOptions;
+class BreakpointPrecondition;
class BreakpointResolver;
class BreakpointSite;
class BreakpointSiteList;
@@ -298,6 +299,7 @@ typedef std::shared_ptr<lldb_private::BreakpointSite> BreakpointSiteSP;
typedef std::weak_ptr<lldb_private::BreakpointSite> BreakpointSiteWP;
typedef std::shared_ptr<lldb_private::BreakpointLocation> BreakpointLocationSP;
typedef std::weak_ptr<lldb_private::BreakpointLocation> BreakpointLocationWP;
+typedef std::shared_ptr<lldb_private::BreakpointPrecondition> BreakpointPreconditionSP;
typedef std::shared_ptr<lldb_private::BreakpointResolver> BreakpointResolverSP;
typedef std::shared_ptr<lldb_private::Broadcaster> BroadcasterSP;
typedef std::shared_ptr<lldb_private::BroadcasterManager> BroadcasterManagerSP;
diff --git a/include/lldb/lldb-private-interfaces.h b/include/lldb/lldb-private-interfaces.h
index 57b25675b..3a9f78aae 100644
--- a/include/lldb/lldb-private-interfaces.h
+++ b/include/lldb/lldb-private-interfaces.h
@@ -55,6 +55,9 @@ typedef LanguageRuntime *(*LanguageRuntimeCreateInstance)(
Process *process, lldb::LanguageType language);
typedef lldb::CommandObjectSP (*LanguageRuntimeGetCommandObject)(
CommandInterpreter &interpreter);
+typedef lldb::BreakpointPreconditionSP (
+ *LanguageRuntimeGetExceptionPrecondition)(lldb::LanguageType language,
+ bool throw_bp);
typedef lldb::StructuredDataPluginSP (*StructuredDataPluginCreateInstance)(
Process &process);
typedef Status (*StructuredDataFilterLaunchInfo)(ProcessLaunchInfo &launch_info,
diff --git a/source/Breakpoint/Breakpoint.cpp b/source/Breakpoint/Breakpoint.cpp
index 0ebba5937..3c3841949 100644
--- a/source/Breakpoint/Breakpoint.cpp
+++ b/source/Breakpoint/Breakpoint.cpp
@@ -11,6 +11,7 @@
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointLocationCollection.h"
+#include "lldb/Breakpoint/BreakpointPrecondition.h"
#include "lldb/Breakpoint/BreakpointResolver.h"
#include "lldb/Breakpoint/BreakpointResolverFileLine.h"
#include "lldb/Core/Address.h"
@@ -995,21 +996,6 @@ bool Breakpoint::EvaluatePrecondition(StoppointCallbackContext &context) {
return m_precondition_sp->EvaluatePrecondition(context);
}
-bool Breakpoint::BreakpointPrecondition::EvaluatePrecondition(
- StoppointCallbackContext &context) {
- return true;
-}
-
-void Breakpoint::BreakpointPrecondition::GetDescription(
- Stream &stream, lldb::DescriptionLevel level) {}
-
-Status
-Breakpoint::BreakpointPrecondition::ConfigurePrecondition(Args &options) {
- Status error;
- error.SetErrorString("Base breakpoint precondition has no options.");
- return error;
-}
-
void Breakpoint::SendBreakpointChangedEvent(
lldb::BreakpointEventType eventKind) {
if (!m_being_created && !IsInternal() &&
diff --git a/source/Breakpoint/BreakpointPrecondition.cpp b/source/Breakpoint/BreakpointPrecondition.cpp
new file mode 100644
index 000000000..a387c75c8
--- /dev/null
+++ b/source/Breakpoint/BreakpointPrecondition.cpp
@@ -0,0 +1,26 @@
+//===-- BreakpointPrecondition.cpp ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Breakpoint/BreakpointPrecondition.h"
+#include "lldb/Utility/Status.h"
+
+using namespace lldb_private;
+
+bool BreakpointPrecondition::EvaluatePrecondition(
+ StoppointCallbackContext &context) {
+ return false;
+}
+
+void BreakpointPrecondition::GetDescription(Stream &stream,
+ lldb::DescriptionLevel level) {}
+
+Status BreakpointPrecondition::ConfigurePrecondition(Args &args) {
+ Status error;
+ error.SetErrorString("Base breakpoint precondition has no options.");
+ return error;
+}
diff --git a/source/Breakpoint/CMakeLists.txt b/source/Breakpoint/CMakeLists.txt
index 439946ca9..a7c0baf21 100644
--- a/source/Breakpoint/CMakeLists.txt
+++ b/source/Breakpoint/CMakeLists.txt
@@ -8,6 +8,7 @@ add_lldb_library(lldbBreakpoint
BreakpointLocationList.cpp
BreakpointName.cpp
BreakpointOptions.cpp
+ BreakpointPrecondition.cpp
BreakpointResolver.cpp
BreakpointResolverAddress.cpp
BreakpointResolverFileLine.cpp
diff --git a/source/Core/PluginManager.cpp b/source/Core/PluginManager.cpp
index cf940dd70..24cadcd85 100644
--- a/source/Core/PluginManager.cpp
+++ b/source/Core/PluginManager.cpp
@@ -828,6 +828,7 @@ struct LanguageRuntimeInstance {
std::string description;
LanguageRuntimeCreateInstance create_callback;
LanguageRuntimeGetCommandObject command_callback;
+ LanguageRuntimeGetExceptionPrecondition precondition_callback;
};
typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
@@ -845,7 +846,8 @@ static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
bool PluginManager::RegisterPlugin(
ConstString name, const char *description,
LanguageRuntimeCreateInstance create_callback,
- LanguageRuntimeGetCommandObject command_callback) {
+ LanguageRuntimeGetCommandObject command_callback,
+ LanguageRuntimeGetExceptionPrecondition precondition_callback) {
if (create_callback) {
LanguageRuntimeInstance instance;
assert((bool)name);
@@ -854,6 +856,7 @@ bool PluginManager::RegisterPlugin(
instance.description = description;
instance.create_callback = create_callback;
instance.command_callback = command_callback;
+ instance.precondition_callback = precondition_callback;
std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
GetLanguageRuntimeInstances().push_back(instance);
}
@@ -895,6 +898,15 @@ PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) {
return nullptr;
}
+LanguageRuntimeGetExceptionPrecondition
+PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
+ LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
+ if (idx < instances.size())
+ return instances[idx].precondition_callback;
+ return nullptr;
+}
+
LanguageRuntimeCreateInstance
PluginManager::GetLanguageRuntimeCreateCallbackForPluginName(
ConstString name) {
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index 49d18c3bb..c8884fd5c 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -85,7 +85,8 @@ AppleObjCRuntimeV1::CreateInstance(Process *process,
void AppleObjCRuntimeV1::Initialize() {
PluginManager::RegisterPlugin(
GetPluginNameStatic(), "Apple Objective-C Language Runtime - Version 1",
- CreateInstance);
+ CreateInstance,
+ /*command_callback = */ nullptr, GetBreakpointExceptionPrecondition);
}
void AppleObjCRuntimeV1::Terminate() {
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index 64dab7e41..c849a5441 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -806,7 +806,8 @@ void AppleObjCRuntimeV2::Initialize() {
CreateInstance,
[](CommandInterpreter &interpreter) -> lldb::CommandObjectSP {
return CommandObjectSP(new CommandObjectMultiwordObjC(interpreter));
- });
+ },
+ GetBreakpointExceptionPrecondition);
}
void AppleObjCRuntimeV2::Terminate() {
diff --git a/source/Target/LanguageRuntime.cpp b/source/Target/LanguageRuntime.cpp
index a75f00854..dd4415810 100644
--- a/source/Target/LanguageRuntime.cpp
+++ b/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,24 @@ LanguageRuntime::LanguageRuntime(Process *process) : m_process(process) {}
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;
+BreakpointPreconditionSP
+LanguageRuntime::GetExceptionPrecondition(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::GetLanguageRuntimeGetExceptionPreconditionAtIndex(
+ idx)) {
+ if (BreakpointPreconditionSP precond =
+ precondition_callback(language, throw_bp))
+ return precond;
+ }
}
- return Breakpoint::BreakpointPreconditionSP();
+ return BreakpointPreconditionSP();
}
BreakpointSP LanguageRuntime::CreateExceptionBreakpoint(
@@ -252,10 +256,8 @@ BreakpointSP LanguageRuntime::CreateExceptionBreakpoint(
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);
+ if (auto precond = GetExceptionPrecondition(language, throw_bp))
+ exc_breakpt_sp->SetPrecondition(precond);
if (is_internal)
exc_breakpt_sp->SetBreakpointKind("exception");
@@ -292,4 +294,3 @@ void LanguageRuntime::InitializeCommands(CommandObject *parent) {
}
}
}
-
diff --git a/source/Target/ObjCLanguageRuntime.cpp b/source/Target/ObjCLanguageRuntime.cpp
index 3084b70e5..ef059a84b 100644
--- a/source/Target/ObjCLanguageRuntime.cpp
+++ b/source/Target/ObjCLanguageRuntime.cpp
@@ -375,6 +375,18 @@ bool ObjCLanguageRuntime::GetTypeBitSize(const CompilerType &compiler_type,
return found;
}
+lldb::BreakpointPreconditionSP
+ObjCLanguageRuntime::GetBreakpointExceptionPrecondition(LanguageType language,
+ bool throw_bp) {
+ if (language != eLanguageTypeObjC)
+ return lldb::BreakpointPreconditionSP();
+ if (!throw_bp)
+ return lldb::BreakpointPreconditionSP();
+ BreakpointPreconditionSP precondition_sp(
+ new ObjCLanguageRuntime::ObjCExceptionPrecondition());
+ return precondition_sp;
+}
+
// Exception breakpoint Precondition class for ObjC:
void ObjCLanguageRuntime::ObjCExceptionPrecondition::AddClassName(
const char *class_name) {
diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp
index 7f68b28c7..5e83ca038 100644
--- a/source/Target/Target.cpp
+++ b/source/Target/Target.cpp
@@ -11,6 +11,7 @@
#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Breakpoint/BreakpointIDList.h"
+#include "lldb/Breakpoint/BreakpointPrecondition.h"
#include "lldb/Breakpoint/BreakpointResolver.h"
#include "lldb/Breakpoint/BreakpointResolverAddress.h"
#include "lldb/Breakpoint/BreakpointResolverFileLine.h"
@@ -573,8 +574,7 @@ Target::CreateExceptionBreakpoint(enum lldb::LanguageType language,
BreakpointSP exc_bkpt_sp = LanguageRuntime::CreateExceptionBreakpoint(
*this, language, catch_bp, throw_bp, internal);
if (exc_bkpt_sp && additional_args) {
- Breakpoint::BreakpointPreconditionSP precondition_sp =
- exc_bkpt_sp->GetPrecondition();
+ BreakpointPreconditionSP precondition_sp = exc_bkpt_sp->GetPrecondition();
if (precondition_sp && additional_args) {
if (error)
*error = precondition_sp->ConfigurePrecondition(*additional_args);