Skip to content

Commit 35fa2de

Browse files
authored
Reapply PR/87550 (#94625)
Re-apply #87550 with fixes. Details: Some tests in fuchsia failed because of the newly added assertion. This was because `GetExceptionBreakpoint()` could be called before `g_dap.debugger` was initted. The fix here is to just lazily populate the list in GetExceptionBreakpoint() rather than assuming it's already been initted. (There is some nuisance here because we can't simply just populate it in DAP::DAP(), which is a global ctor and is called before `SBDebugger::Initialize()` is called. )
1 parent e9adcc4 commit 35fa2de

File tree

7 files changed

+77
-13
lines changed

7 files changed

+77
-13
lines changed

lldb/include/lldb/API/SBDebugger.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ class LLDB_API SBDebugger {
5757

5858
static const char *GetBroadcasterClass();
5959

60+
static bool SupportsLanguage(lldb::LanguageType language);
61+
6062
lldb::SBBroadcaster GetBroadcaster();
6163

6264
/// Get progress data from a SBEvent whose type is eBroadcastBitProgress.

lldb/include/lldb/Symbol/TypeSystem.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ class TypeSystem : public PluginInterface,
209209
// TypeSystems can support more than one language
210210
virtual bool SupportsLanguage(lldb::LanguageType language) = 0;
211211

212+
static bool SupportsLanguageStatic(lldb::LanguageType language);
212213
// Type Completion
213214

214215
virtual bool GetCompleteType(lldb::opaque_compiler_type_t type) = 0;

lldb/source/API/SBDebugger.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1742,3 +1742,7 @@ bool SBDebugger::InterruptRequested() {
17421742
return m_opaque_sp->InterruptRequested();
17431743
return false;
17441744
}
1745+
1746+
bool SBDebugger::SupportsLanguage(lldb::LanguageType language) {
1747+
return TypeSystem::SupportsLanguageStatic(language);
1748+
}

lldb/source/Symbol/TypeSystem.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,3 +335,14 @@ TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
335335
}
336336
return GetTypeSystemForLanguage(language);
337337
}
338+
339+
bool TypeSystem::SupportsLanguageStatic(lldb::LanguageType language) {
340+
if (language == eLanguageTypeUnknown)
341+
return false;
342+
343+
LanguageSet languages =
344+
PluginManager::GetAllTypeSystemSupportedLanguagesForTypes();
345+
if (languages.Empty())
346+
return false;
347+
return languages[language];
348+
}

lldb/tools/lldb-dap/DAP.cpp

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,7 @@ namespace lldb_dap {
3232
DAP g_dap;
3333

3434
DAP::DAP()
35-
: broadcaster("lldb-dap"),
36-
exception_breakpoints(
37-
{{"cpp_catch", "C++ Catch", lldb::eLanguageTypeC_plus_plus},
38-
{"cpp_throw", "C++ Throw", lldb::eLanguageTypeC_plus_plus},
39-
{"objc_catch", "Objective-C Catch", lldb::eLanguageTypeObjC},
40-
{"objc_throw", "Objective-C Throw", lldb::eLanguageTypeObjC},
41-
{"swift_catch", "Swift Catch", lldb::eLanguageTypeSwift},
42-
{"swift_throw", "Swift Throw", lldb::eLanguageTypeSwift}}),
35+
: broadcaster("lldb-dap"), exception_breakpoints(),
4336
focus_tid(LLDB_INVALID_THREAD_ID), stop_at_entry(false), is_attach(false),
4437
enable_auto_variable_summaries(false),
4538
enable_synthetic_child_debugging(false),
@@ -65,16 +58,64 @@ DAP::DAP()
6558

6659
DAP::~DAP() = default;
6760

61+
void DAP::PopulateExceptionBreakpoints() {
62+
llvm::call_once(initExceptionBreakpoints, [this]() {
63+
exception_breakpoints = {};
64+
if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeC_plus_plus)) {
65+
exception_breakpoints->emplace_back("cpp_catch", "C++ Catch",
66+
lldb::eLanguageTypeC_plus_plus);
67+
exception_breakpoints->emplace_back("cpp_throw", "C++ Throw",
68+
lldb::eLanguageTypeC_plus_plus);
69+
}
70+
if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeObjC)) {
71+
exception_breakpoints->emplace_back("objc_catch", "Objective-C Catch",
72+
lldb::eLanguageTypeObjC);
73+
exception_breakpoints->emplace_back("objc_throw", "Objective-C Throw",
74+
lldb::eLanguageTypeObjC);
75+
}
76+
if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeSwift)) {
77+
exception_breakpoints->emplace_back("swift_catch", "Swift Catch",
78+
lldb::eLanguageTypeSwift);
79+
exception_breakpoints->emplace_back("swift_throw", "Swift Throw",
80+
lldb::eLanguageTypeSwift);
81+
}
82+
});
83+
}
84+
6885
ExceptionBreakpoint *DAP::GetExceptionBreakpoint(const std::string &filter) {
69-
for (auto &bp : exception_breakpoints) {
86+
// PopulateExceptionBreakpoints() is called after g_dap.debugger is created
87+
// in a request-initialize.
88+
//
89+
// But this GetExceptionBreakpoint() method may be called before attaching, in
90+
// which case, we may not have populated the filter yet.
91+
//
92+
// We also cannot call PopulateExceptionBreakpoints() in DAP::DAP() because
93+
// we need SBDebugger::Initialize() to have been called before this.
94+
//
95+
// So just calling PopulateExceptionBreakoints(),which does lazy-populating
96+
// seems easiest. Two other options include:
97+
// + call g_dap.PopulateExceptionBreakpoints() in lldb-dap.cpp::main()
98+
// right after the call to SBDebugger::Initialize()
99+
// + Just call PopulateExceptionBreakpoints() to get a fresh list everytime
100+
// we query (a bit overkill since it's not likely to change?)
101+
PopulateExceptionBreakpoints();
102+
assert(exception_breakpoints.has_value() &&
103+
"exception_breakpoints must have been populated");
104+
105+
for (auto &bp : *exception_breakpoints) {
70106
if (bp.filter == filter)
71107
return &bp;
72108
}
73109
return nullptr;
74110
}
75111

76112
ExceptionBreakpoint *DAP::GetExceptionBreakpoint(const lldb::break_id_t bp_id) {
77-
for (auto &bp : exception_breakpoints) {
113+
// See comment in the other GetExceptionBreakpoint().
114+
PopulateExceptionBreakpoints();
115+
assert(exception_breakpoints.has_value() &&
116+
"exception_breakpoints must have been populated");
117+
118+
for (auto &bp : *exception_breakpoints) {
78119
if (bp.bp.GetID() == bp_id)
79120
return &bp;
80121
}

lldb/tools/lldb-dap/DAP.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ struct DAP {
156156
std::unique_ptr<std::ofstream> log;
157157
llvm::StringMap<SourceBreakpointMap> source_breakpoints;
158158
FunctionBreakpointMap function_breakpoints;
159-
std::vector<ExceptionBreakpoint> exception_breakpoints;
159+
std::optional<std::vector<ExceptionBreakpoint>> exception_breakpoints;
160+
llvm::once_flag initExceptionBreakpoints;
160161
std::vector<std::string> init_commands;
161162
std::vector<std::string> pre_run_commands;
162163
std::vector<std::string> post_run_commands;
@@ -228,6 +229,8 @@ struct DAP {
228229

229230
llvm::json::Value CreateTopLevelScopes();
230231

232+
void PopulateExceptionBreakpoints();
233+
231234
/// \return
232235
/// Attempt to determine if an expression is a variable expression or
233236
/// lldb command using a hueristic based on the first term of the

lldb/tools/lldb-dap/lldb-dap.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <cstdio>
1717
#include <cstdlib>
1818
#include <cstring>
19+
#include <optional>
1920
#include <sys/stat.h>
2021
#include <sys/types.h>
2122
#if defined(_WIN32)
@@ -1586,6 +1587,7 @@ void request_initialize(const llvm::json::Object &request) {
15861587
bool source_init_file = GetBoolean(arguments, "sourceInitFile", true);
15871588

15881589
g_dap.debugger = lldb::SBDebugger::Create(source_init_file, log_cb, nullptr);
1590+
g_dap.PopulateExceptionBreakpoints();
15891591
auto cmd = g_dap.debugger.GetCommandInterpreter().AddMultiwordCommand(
15901592
"lldb-dap", "Commands for managing lldb-dap.");
15911593
if (GetBoolean(arguments, "supportsStartDebuggingRequest", false)) {
@@ -1621,7 +1623,7 @@ void request_initialize(const llvm::json::Object &request) {
16211623
body.try_emplace("supportsEvaluateForHovers", true);
16221624
// Available filters or options for the setExceptionBreakpoints request.
16231625
llvm::json::Array filters;
1624-
for (const auto &exc_bp : g_dap.exception_breakpoints) {
1626+
for (const auto &exc_bp : *g_dap.exception_breakpoints) {
16251627
filters.emplace_back(CreateExceptionBreakpointFilter(exc_bp));
16261628
}
16271629
body.try_emplace("exceptionBreakpointFilters", std::move(filters));
@@ -2476,7 +2478,7 @@ void request_setExceptionBreakpoints(const llvm::json::Object &request) {
24762478
// Keep a list of any exception breakpoint filter names that weren't set
24772479
// so we can clear any exception breakpoints if needed.
24782480
std::set<std::string> unset_filters;
2479-
for (const auto &bp : g_dap.exception_breakpoints)
2481+
for (const auto &bp : *g_dap.exception_breakpoints)
24802482
unset_filters.insert(bp.filter);
24812483

24822484
for (const auto &value : *filters) {

0 commit comments

Comments
 (0)