Skip to content

Commit 7f9c9f2

Browse files
committed
[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 llvm-svn: 364098
1 parent 4649a05 commit 7f9c9f2

File tree

16 files changed

+135
-65
lines changed

16 files changed

+135
-65
lines changed

lldb/include/lldb/Breakpoint/Breakpoint.h

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -140,19 +140,6 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
140140
DISALLOW_COPY_AND_ASSIGN(BreakpointEventData);
141141
};
142142

143-
class BreakpointPrecondition {
144-
public:
145-
virtual ~BreakpointPrecondition() = default;
146-
147-
virtual bool EvaluatePrecondition(StoppointCallbackContext &context);
148-
149-
virtual Status ConfigurePrecondition(Args &options);
150-
151-
virtual void GetDescription(Stream &stream, lldb::DescriptionLevel level);
152-
};
153-
154-
typedef std::shared_ptr<BreakpointPrecondition> BreakpointPreconditionSP;
155-
156143
// Saving & restoring breakpoints:
157144
static lldb::BreakpointSP CreateFromStructuredData(
158145
Target &target, StructuredData::ObjectSP &data_object_sp, Status &error);
@@ -558,14 +545,14 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
558545
/// The Precondition should not continue the target, it should return true
559546
/// if the condition says to stop and false otherwise.
560547
///
561-
void SetPrecondition(BreakpointPreconditionSP precondition_sp) {
548+
void SetPrecondition(lldb::BreakpointPreconditionSP precondition_sp) {
562549
m_precondition_sp = precondition_sp;
563550
}
564551

565552
bool EvaluatePrecondition(StoppointCallbackContext &context);
566553

567-
BreakpointPreconditionSP GetPrecondition() { return m_precondition_sp; }
568-
554+
lldb::BreakpointPreconditionSP GetPrecondition() { return m_precondition_sp; }
555+
569556
// Produces the OR'ed values for all the names assigned to this breakpoint.
570557
const BreakpointName::Permissions &GetPermissions() const {
571558
return m_permissions;
@@ -659,9 +646,9 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
659646
m_filter_sp; // The filter that constrains the breakpoint's domain.
660647
lldb::BreakpointResolverSP
661648
m_resolver_sp; // The resolver that defines this breakpoint.
662-
BreakpointPreconditionSP m_precondition_sp; // The precondition is a
663-
// breakpoint-level hit filter
664-
// that can be used
649+
lldb::BreakpointPreconditionSP m_precondition_sp; // The precondition is a
650+
// breakpoint-level hit
651+
// filter that can be used
665652
// to skip certain breakpoint hits. For instance, exception breakpoints use
666653
// this to limit the stop to certain exception classes, while leaving the
667654
// condition & callback free for user specification.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//===-- BreakpointPrecondition.h --------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef liblldb_BreakpointPrecondition_h_
10+
#define liblldb_BreakpointPrecondition_h_
11+
12+
#include "lldb/lldb-enumerations.h"
13+
14+
namespace lldb_private {
15+
16+
class Args;
17+
class Status;
18+
class StoppointCallbackContext;
19+
class Stream;
20+
21+
class BreakpointPrecondition {
22+
public:
23+
virtual ~BreakpointPrecondition() = default;
24+
virtual bool EvaluatePrecondition(StoppointCallbackContext &context);
25+
virtual Status ConfigurePrecondition(Args &args);
26+
virtual void GetDescription(Stream &stream, lldb::DescriptionLevel level);
27+
};
28+
} // namespace lldb_private
29+
30+
#endif

lldb/include/lldb/Core/PluginManager.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,11 @@ class PluginManager {
134134
GetLanguageCreateCallbackForPluginName(ConstString name);
135135

136136
// LanguageRuntime
137-
static bool
138-
RegisterPlugin(ConstString name, const char *description,
139-
LanguageRuntimeCreateInstance create_callback,
140-
LanguageRuntimeGetCommandObject command_callback = nullptr);
137+
static bool RegisterPlugin(
138+
ConstString name, const char *description,
139+
LanguageRuntimeCreateInstance create_callback,
140+
LanguageRuntimeGetCommandObject command_callback = nullptr,
141+
LanguageRuntimeGetExceptionPrecondition precondition_callback = nullptr);
141142

142143
static bool UnregisterPlugin(LanguageRuntimeCreateInstance create_callback);
143144

@@ -147,6 +148,9 @@ class PluginManager {
147148
static LanguageRuntimeGetCommandObject
148149
GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx);
149150

151+
static LanguageRuntimeGetExceptionPrecondition
152+
GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx);
153+
150154
static LanguageRuntimeCreateInstance
151155
GetLanguageRuntimeCreateCallbackForPluginName(ConstString name);
152156

lldb/include/lldb/Target/LanguageRuntime.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,8 @@ class LanguageRuntime : public PluginInterface {
115115
bool catch_bp, bool throw_bp,
116116
bool is_internal = false);
117117

118-
static Breakpoint::BreakpointPreconditionSP
119-
CreateExceptionPrecondition(lldb::LanguageType language, bool catch_bp,
120-
bool throw_bp);
118+
static lldb::BreakpointPreconditionSP
119+
GetExceptionPrecondition(lldb::LanguageType language, bool throw_bp);
121120

122121
virtual lldb::ValueObjectSP GetExceptionObjectForThread(
123122
lldb::ThreadSP thread_sp) {

lldb/include/lldb/Target/ObjCLanguageRuntime.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "llvm/Support/Casting.h"
1818

19+
#include "lldb/Breakpoint/BreakpointPrecondition.h"
1920
#include "lldb/Core/PluginInterface.h"
2021
#include "lldb/Core/ThreadSafeDenseMap.h"
2122
#include "lldb/Symbol/CompilerType.h"
@@ -154,7 +155,7 @@ class ObjCLanguageRuntime : public LanguageRuntime {
154155
std::unique_ptr<ClangASTContext> m_scratch_ast_ctx_up;
155156
};
156157

157-
class ObjCExceptionPrecondition : public Breakpoint::BreakpointPrecondition {
158+
class ObjCExceptionPrecondition : public BreakpointPrecondition {
158159
public:
159160
ObjCExceptionPrecondition();
160161

@@ -171,6 +172,10 @@ class ObjCLanguageRuntime : public LanguageRuntime {
171172
std::unordered_set<std::string> m_class_names;
172173
};
173174

175+
static lldb::BreakpointPreconditionSP
176+
GetBreakpointExceptionPrecondition(lldb::LanguageType language,
177+
bool throw_bp);
178+
174179
class TaggedPointerVendor {
175180
public:
176181
virtual ~TaggedPointerVendor() = default;

lldb/include/lldb/lldb-forward.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class BreakpointLocationList;
3737
class BreakpointName;
3838
class BreakpointOptionGroup;
3939
class BreakpointOptions;
40+
class BreakpointPrecondition;
4041
class BreakpointResolver;
4142
class BreakpointSite;
4243
class BreakpointSiteList;
@@ -298,6 +299,7 @@ typedef std::shared_ptr<lldb_private::BreakpointSite> BreakpointSiteSP;
298299
typedef std::weak_ptr<lldb_private::BreakpointSite> BreakpointSiteWP;
299300
typedef std::shared_ptr<lldb_private::BreakpointLocation> BreakpointLocationSP;
300301
typedef std::weak_ptr<lldb_private::BreakpointLocation> BreakpointLocationWP;
302+
typedef std::shared_ptr<lldb_private::BreakpointPrecondition> BreakpointPreconditionSP;
301303
typedef std::shared_ptr<lldb_private::BreakpointResolver> BreakpointResolverSP;
302304
typedef std::shared_ptr<lldb_private::Broadcaster> BroadcasterSP;
303305
typedef std::shared_ptr<lldb_private::BroadcasterManager> BroadcasterManagerSP;

lldb/include/lldb/lldb-private-interfaces.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ typedef LanguageRuntime *(*LanguageRuntimeCreateInstance)(
5555
Process *process, lldb::LanguageType language);
5656
typedef lldb::CommandObjectSP (*LanguageRuntimeGetCommandObject)(
5757
CommandInterpreter &interpreter);
58+
typedef lldb::BreakpointPreconditionSP (
59+
*LanguageRuntimeGetExceptionPrecondition)(lldb::LanguageType language,
60+
bool throw_bp);
5861
typedef lldb::StructuredDataPluginSP (*StructuredDataPluginCreateInstance)(
5962
Process &process);
6063
typedef Status (*StructuredDataFilterLaunchInfo)(ProcessLaunchInfo &launch_info,

lldb/source/Breakpoint/Breakpoint.cpp

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "lldb/Breakpoint/Breakpoint.h"
1212
#include "lldb/Breakpoint/BreakpointLocation.h"
1313
#include "lldb/Breakpoint/BreakpointLocationCollection.h"
14+
#include "lldb/Breakpoint/BreakpointPrecondition.h"
1415
#include "lldb/Breakpoint/BreakpointResolver.h"
1516
#include "lldb/Breakpoint/BreakpointResolverFileLine.h"
1617
#include "lldb/Core/Address.h"
@@ -995,21 +996,6 @@ bool Breakpoint::EvaluatePrecondition(StoppointCallbackContext &context) {
995996
return m_precondition_sp->EvaluatePrecondition(context);
996997
}
997998

998-
bool Breakpoint::BreakpointPrecondition::EvaluatePrecondition(
999-
StoppointCallbackContext &context) {
1000-
return true;
1001-
}
1002-
1003-
void Breakpoint::BreakpointPrecondition::GetDescription(
1004-
Stream &stream, lldb::DescriptionLevel level) {}
1005-
1006-
Status
1007-
Breakpoint::BreakpointPrecondition::ConfigurePrecondition(Args &options) {
1008-
Status error;
1009-
error.SetErrorString("Base breakpoint precondition has no options.");
1010-
return error;
1011-
}
1012-
1013999
void Breakpoint::SendBreakpointChangedEvent(
10141000
lldb::BreakpointEventType eventKind) {
10151001
if (!m_being_created && !IsInternal() &&
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===-- BreakpointPrecondition.cpp ------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "lldb/Breakpoint/BreakpointPrecondition.h"
10+
#include "lldb/Utility/Status.h"
11+
12+
using namespace lldb_private;
13+
14+
bool BreakpointPrecondition::EvaluatePrecondition(
15+
StoppointCallbackContext &context) {
16+
return false;
17+
}
18+
19+
void BreakpointPrecondition::GetDescription(Stream &stream,
20+
lldb::DescriptionLevel level) {}
21+
22+
Status BreakpointPrecondition::ConfigurePrecondition(Args &args) {
23+
Status error;
24+
error.SetErrorString("Base breakpoint precondition has no options.");
25+
return error;
26+
}

lldb/source/Breakpoint/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ add_lldb_library(lldbBreakpoint
88
BreakpointLocationList.cpp
99
BreakpointName.cpp
1010
BreakpointOptions.cpp
11+
BreakpointPrecondition.cpp
1112
BreakpointResolver.cpp
1213
BreakpointResolverAddress.cpp
1314
BreakpointResolverFileLine.cpp

lldb/source/Core/PluginManager.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,7 @@ struct LanguageRuntimeInstance {
828828
std::string description;
829829
LanguageRuntimeCreateInstance create_callback;
830830
LanguageRuntimeGetCommandObject command_callback;
831+
LanguageRuntimeGetExceptionPrecondition precondition_callback;
831832
};
832833

833834
typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
@@ -845,7 +846,8 @@ static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
845846
bool PluginManager::RegisterPlugin(
846847
ConstString name, const char *description,
847848
LanguageRuntimeCreateInstance create_callback,
848-
LanguageRuntimeGetCommandObject command_callback) {
849+
LanguageRuntimeGetCommandObject command_callback,
850+
LanguageRuntimeGetExceptionPrecondition precondition_callback) {
849851
if (create_callback) {
850852
LanguageRuntimeInstance instance;
851853
assert((bool)name);
@@ -854,6 +856,7 @@ bool PluginManager::RegisterPlugin(
854856
instance.description = description;
855857
instance.create_callback = create_callback;
856858
instance.command_callback = command_callback;
859+
instance.precondition_callback = precondition_callback;
857860
std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
858861
GetLanguageRuntimeInstances().push_back(instance);
859862
}
@@ -895,6 +898,15 @@ PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) {
895898
return nullptr;
896899
}
897900

901+
LanguageRuntimeGetExceptionPrecondition
902+
PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx) {
903+
std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
904+
LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
905+
if (idx < instances.size())
906+
return instances[idx].precondition_callback;
907+
return nullptr;
908+
}
909+
898910
LanguageRuntimeCreateInstance
899911
PluginManager::GetLanguageRuntimeCreateCallbackForPluginName(
900912
ConstString name) {

lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ AppleObjCRuntimeV1::CreateInstance(Process *process,
8585
void AppleObjCRuntimeV1::Initialize() {
8686
PluginManager::RegisterPlugin(
8787
GetPluginNameStatic(), "Apple Objective-C Language Runtime - Version 1",
88-
CreateInstance);
88+
CreateInstance,
89+
/*command_callback = */ nullptr, GetBreakpointExceptionPrecondition);
8990
}
9091

9192
void AppleObjCRuntimeV1::Terminate() {

lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,8 @@ void AppleObjCRuntimeV2::Initialize() {
806806
CreateInstance,
807807
[](CommandInterpreter &interpreter) -> lldb::CommandObjectSP {
808808
return CommandObjectSP(new CommandObjectMultiwordObjC(interpreter));
809-
});
809+
},
810+
GetBreakpointExceptionPrecondition);
810811
}
811812

812813
void AppleObjCRuntimeV2::Terminate() {

lldb/source/Target/LanguageRuntime.cpp

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#include "lldb/Core/SearchFilter.h"
1212
#include "lldb/Interpreter/CommandInterpreter.h"
1313
#include "lldb/Target/Language.h"
14-
#include "lldb/Target/ObjCLanguageRuntime.h"
1514
#include "lldb/Target/Target.h"
1615

1716
using namespace lldb;
@@ -224,19 +223,24 @@ LanguageRuntime::LanguageRuntime(Process *process) : m_process(process) {}
224223

225224
LanguageRuntime::~LanguageRuntime() = default;
226225

227-
Breakpoint::BreakpointPreconditionSP
228-
LanguageRuntime::CreateExceptionPrecondition(lldb::LanguageType language,
229-
bool catch_bp, bool throw_bp) {
230-
switch (language) {
231-
case eLanguageTypeObjC:
232-
if (throw_bp)
233-
return Breakpoint::BreakpointPreconditionSP(
234-
new ObjCLanguageRuntime::ObjCExceptionPrecondition());
235-
break;
236-
default:
237-
break;
226+
BreakpointPreconditionSP
227+
LanguageRuntime::GetExceptionPrecondition(LanguageType language,
228+
bool throw_bp) {
229+
LanguageRuntimeCreateInstance create_callback;
230+
for (uint32_t idx = 0;
231+
(create_callback =
232+
PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) !=
233+
nullptr;
234+
idx++) {
235+
if (auto precondition_callback =
236+
PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(
237+
idx)) {
238+
if (BreakpointPreconditionSP precond =
239+
precondition_callback(language, throw_bp))
240+
return precond;
241+
}
238242
}
239-
return Breakpoint::BreakpointPreconditionSP();
243+
return BreakpointPreconditionSP();
240244
}
241245

242246
BreakpointSP LanguageRuntime::CreateExceptionBreakpoint(
@@ -252,10 +256,8 @@ BreakpointSP LanguageRuntime::CreateExceptionBreakpoint(
252256
target.CreateBreakpoint(filter_sp, resolver_sp, is_internal, hardware,
253257
resolve_indirect_functions));
254258
if (exc_breakpt_sp) {
255-
Breakpoint::BreakpointPreconditionSP precondition_sp =
256-
CreateExceptionPrecondition(language, catch_bp, throw_bp);
257-
if (precondition_sp)
258-
exc_breakpt_sp->SetPrecondition(precondition_sp);
259+
if (auto precond = GetExceptionPrecondition(language, throw_bp))
260+
exc_breakpt_sp->SetPrecondition(precond);
259261

260262
if (is_internal)
261263
exc_breakpt_sp->SetBreakpointKind("exception");
@@ -292,4 +294,3 @@ void LanguageRuntime::InitializeCommands(CommandObject *parent) {
292294
}
293295
}
294296
}
295-

lldb/source/Target/ObjCLanguageRuntime.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,18 @@ bool ObjCLanguageRuntime::GetTypeBitSize(const CompilerType &compiler_type,
375375
return found;
376376
}
377377

378+
lldb::BreakpointPreconditionSP
379+
ObjCLanguageRuntime::GetBreakpointExceptionPrecondition(LanguageType language,
380+
bool throw_bp) {
381+
if (language != eLanguageTypeObjC)
382+
return lldb::BreakpointPreconditionSP();
383+
if (!throw_bp)
384+
return lldb::BreakpointPreconditionSP();
385+
BreakpointPreconditionSP precondition_sp(
386+
new ObjCLanguageRuntime::ObjCExceptionPrecondition());
387+
return precondition_sp;
388+
}
389+
378390
// Exception breakpoint Precondition class for ObjC:
379391
void ObjCLanguageRuntime::ObjCExceptionPrecondition::AddClassName(
380392
const char *class_name) {

0 commit comments

Comments
 (0)