-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[lldb][lldb-dap] Cleanup breakpoint filters. #87550
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-lldb Author: Vy Nguyen (oontvoo) ChangesDetails:
Full diff: https://github.com/llvm/llvm-project/pull/87550.diff 2 Files Affected:
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index b254ddfef0d5ff..52e607350407ab 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -36,9 +36,7 @@ DAP::DAP()
{{"cpp_catch", "C++ Catch", lldb::eLanguageTypeC_plus_plus},
{"cpp_throw", "C++ Throw", lldb::eLanguageTypeC_plus_plus},
{"objc_catch", "Objective-C Catch", lldb::eLanguageTypeObjC},
- {"objc_throw", "Objective-C Throw", lldb::eLanguageTypeObjC},
- {"swift_catch", "Swift Catch", lldb::eLanguageTypeSwift},
- {"swift_throw", "Swift Throw", lldb::eLanguageTypeSwift}}),
+ {"objc_throw", "Objective-C Throw", lldb::eLanguageTypeObjC}}),
focus_tid(LLDB_INVALID_THREAD_ID), sent_terminated_event(false),
stop_at_entry(false), is_attach(false),
enable_auto_variable_summaries(false),
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index 55f8c920e60016..5f5014eaab90f0 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -1628,7 +1628,14 @@ void request_initialize(const llvm::json::Object &request) {
body.try_emplace("supportsEvaluateForHovers", true);
// Available filters or options for the setExceptionBreakpoints request.
llvm::json::Array filters;
+ std::string triple =
+ std::string(g_dap.debugger.GetSelectedPlatform().GetTriple());
for (const auto &exc_bp : g_dap.exception_breakpoints) {
+ // Skipping objc breakpoint filters if not working on macos.
+ if (exc_bp.language == lldb::eLanguageTypeObjC &&
+ triple.find("macos") == std::string::npos) {
+ continue;
+ }
filters.emplace_back(CreateExceptionBreakpointFilter(exc_bp));
}
body.try_emplace("exceptionBreakpointFilters", std::move(filters));
|
lldb/tools/lldb-dap/lldb-dap.cpp
Outdated
for (const auto &exc_bp : g_dap.exception_breakpoints) { | ||
// Skipping objc breakpoint filters if not working on macos. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GNUStep is still a thing. It's likely the exception throw breakpoint is the only part of our ObjC support that would work with GNUStep, however, so maybe this doesn't matter all that much.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be nice if we can detect if we support Swift dynamically. Internally in LLDB, we can ask for a TypeSystem by language using:
llvm::Expected<lldb::TypeSystemSP>
TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
Module *module, bool can_create);
llvm::Expected<lldb::TypeSystemSP>
TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
Target *target, bool can_create);
These functions will return respectively:
TypeSystem::CreateInstance(language, module);
TypeSystem::CreateInstance(language, target);
We should be able to add a new static method to the TypeSystem.h/.cpp that can answer if a language is supported with something like:
static bool TypeSystem::SupportsLanguage(lldb::LanguageType language);
Each TypeSystem plugin can register a new callback that can answer if they support a language. Then we can add a static function on SBDebugger that would expose this function with something like:
static bool SBDebugger::SupportsLanguage(lldb::LanguageType language);
I will make comments in the DAP.cpp where this would be used.
lldb/tools/lldb-dap/DAP.cpp
Outdated
{{"cpp_catch", "C++ Catch", lldb::eLanguageTypeC_plus_plus}, | ||
{"cpp_throw", "C++ Throw", lldb::eLanguageTypeC_plus_plus}, | ||
{"objc_catch", "Objective-C Catch", lldb::eLanguageTypeObjC}, | ||
{"objc_throw", "Objective-C Throw", lldb::eLanguageTypeObjC}, | ||
{"swift_catch", "Swift Catch", lldb::eLanguageTypeSwift}, | ||
{"swift_throw", "Swift Throw", lldb::eLanguageTypeSwift}}), | ||
{"objc_throw", "Objective-C Throw", lldb::eLanguageTypeObjC}}), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comments for this patch in the review. It would be great to determine if a language is supported by LLDB dynamically and only add support for languages that the current LLDB supports. So we would probably need to default construct the exception_breakpoints()
and then inside this constructor or before we try to use exception_breakpoints
, we would need to populate it by doing something like:
if (g_dap.debugger.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 (g_dap.debugger.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 (g_dap.debugger.SupportsLanguage(lldb:: eLanguageTypeSwift)) {
exception_breakpoints.emplace_back({"swift_catch", "Swift Catch", lldb:: eLanguageTypeSwift})
exception_breakpoints.emplace_back("swift_throw", "Swift Throw", lldb:: eLanguageTypeSwift})
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the detailed suggestions! Makes sense!
For ObjC, just to clarify, the intention of hiding the filters was NOT because the debugger didn't support it - the intention was to avoid clustering/confusing users - that is, if they're not debugging ObjC, there's no reason to show the objc filters. (And we infer this by checking if they're debugging on a mac - it's theoretically possible they're cross debugging objc from a non-mac but in practice I don't think it's likely )
Does this seem reasonable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ObjC Language runtime is able to detect whether ObjC is loaded into the program. It runs that detector on each library load, so it keeps an accurate notion of this. Ditto for the swift language runtime. It would be better to consult that than guess based on platform. There may not currently be a way to ask that from the SB API's but we can certainly make one...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ObjC Language runtime is able to detect whether ObjC is loaded into the program. It runs that detector on each library load, so it keeps an accurate notion of this. Ditto for the swift language runtime. It would be better to consult that than guess based on platform.
This code runs before the runtimes (objc/swift) so it probably won't be able to query that, though?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P.S: it was pointed out to me that changed capabilities can be pushed as an event. So I guess we could init the list of filters based on whether the languages are supported. Then when the runtime(s) become available, we can update the list after querying for which language is being debugged. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ObjC tends to only use exceptions for error reporting, not for message passing, so a lot of ObjC developers leave this breakpoint on all the time. Having to wait till the first load event that brings in ObjC would make that tedious.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, it's possible to register typesystems/languages at initialization via runtime plugins. I think it would be ideal if the breakpoint list could get updated/refreshed after the target has been loaded (maybe at the first stop point)
See also how lldb/test/Shell/Process/UnsupportedLanguage.test works |
lldb/tools/lldb-dap/lldb-dap.cpp
Outdated
for (const auto &exc_bp : g_dap.exception_breakpoints) { | ||
// Skipping objc breakpoint filters if not working on macos. | ||
if (exc_bp.language == lldb::eLanguageTypeObjC && | ||
triple.find("macos") == std::string::npos) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition to what Jim said above, this might not always work. For example, there are more apple triples (e.g. arm64-apple-ios
)
- added util function for querying whether a language is supported by the type system - populate the breakpoint filters table based on the supported language(s)
Done! |
lldb/source/Symbol/TypeSystem.cpp
Outdated
LanguageSet plugins = | ||
PluginManager::GetAllTypeSystemSupportedLanguagesForTypes(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/plugins/languages/
lldb/tools/lldb-dap/DAP.h
Outdated
@@ -331,6 +333,7 @@ struct DAP { | |||
// "Content-Length:" field followed by the length, followed by the raw | |||
// JSON bytes. | |||
void SendJSON(const std::string &json_str); | |||
bool bp_initted; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be next to exception_breakpoints
, but I wouldn't bother with the boolean and instead make exception_breakpoints
a std::optional<...>
and initialize it in PopulateExceptionBreakpoints
so that the two are inherently tied together.
- use std::optional - rename plugins->languages
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
@clayborg Hi, do you have any further comments/feedback on this? Thanks! |
We started seeing lldb test failures in
|
This reverts commit cfb209b.
Reverts #87550 because it broke `TestDAP*` lldb tests. https://luci-milo.appspot.com/ui/p/fuchsia/builders/toolchain.ci/clang-linux-x64-rbe/b8746585790559468897/overview
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. )
@oontvoo I think this broke the bots again: https://green.lab.llvm.org/job/llvm.org/view/LLDB/job/as-lldb-cmake/5341/console |
Would you mind reverting it until you have a chance to look at the failures? |
Details: