================
@@ -65,16 +58,60 @@ DAP::DAP()
 
 DAP::~DAP() = default;
 
+void DAP::PopulateExceptionBreakpoints() {
+  exception_breakpoints = {};
+  if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeC_plus_plus)) {
+    exception_breakpoints->emplace_back("cpp_catch", "C++ Catch",
+                                        lldb::eLanguageTypeC_plus_plus);
+    exception_breakpoints->emplace_back("cpp_throw", "C++ Throw",
+                                        lldb::eLanguageTypeC_plus_plus);
+  }
+  if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeObjC)) {
+    exception_breakpoints->emplace_back("objc_catch", "Objective-C Catch",
+                                        lldb::eLanguageTypeObjC);
+    exception_breakpoints->emplace_back("objc_throw", "Objective-C Throw",
+                                        lldb::eLanguageTypeObjC);
+  }
+  if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeSwift)) {
+    exception_breakpoints->emplace_back("swift_catch", "Swift Catch",
+                                        lldb::eLanguageTypeSwift);
+    exception_breakpoints->emplace_back("swift_throw", "Swift Throw",
+                                        lldb::eLanguageTypeSwift);
+  }
+}
+
 ExceptionBreakpoint *DAP::GetExceptionBreakpoint(const std::string &filter) {
-  for (auto &bp : exception_breakpoints) {
+  // PopulateExceptionBreakpoints() is called after g_dap.debugger is created
+  // in a request-initialize.
+  //
+  // But this GetExceptionBreakpoint() method may be called before attaching, 
in
+  // which case, we may not have populated the filter yet.
+  //
+  // We also cannot call PopulateExceptionBreakpoints() in DAP::DAP() because
+  // we need SBDebugger::Initialize() to have been called before this.
+  //
+  // So just checking the filter list and do lazy-populating seems easiest.
+  // Two other options include:
+  //  + call g_dap.PopulateExceptionBreakpoints() in lldb-dap.cpp::main()
+  //    right after the call to SBDebugger::Initialize()
+  //  + Just call PopulateExceptionBreakpoints() to get a fresh list  everytime
+  //    we query (a bit overkill since it's not likely to change?)
+  if (!exception_breakpoints.has_value())
----------------
JDevlieghere wrote:

You could avoid having to duplicate this check (and the comment) by hoisting it 
into `PopulateExceptionBreakpoints` and call it unconditionally here. 

You can keep an assert to convey the precondition is that 
`PopulateExceptionBreakpoints` must have been called:

```
assert(exception_breakpoints && "PopulateExceptionBreakpoints must be called")
```

I'm not familiar enough with the code to know if there's a risk of racing on 
that variable, but if I was implementing the lazy approach, I would wrap the 
thing into a `call_once`. If there's no risk of multiple threads calling 
`GetExceptionBreakpoint` then this might be overkill and checking the optional 
is sufficient and marginally more efficient. 

https://github.com/llvm/llvm-project/pull/94625
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to