@@ -32,14 +32,7 @@ namespace lldb_dap {
32
32
DAP g_dap;
33
33
34
34
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(),
43
36
focus_tid (LLDB_INVALID_THREAD_ID), stop_at_entry(false ), is_attach(false ),
44
37
enable_auto_variable_summaries(false ),
45
38
enable_synthetic_child_debugging(false ),
@@ -65,16 +58,64 @@ DAP::DAP()
65
58
66
59
DAP::~DAP () = default ;
67
60
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
+
68
85
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) {
70
106
if (bp.filter == filter)
71
107
return &bp;
72
108
}
73
109
return nullptr ;
74
110
}
75
111
76
112
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) {
78
119
if (bp.bp .GetID () == bp_id)
79
120
return &bp;
80
121
}
0 commit comments