-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[lldb][Commands] Check that modules reports that they're loaded #66144
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
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-lldb ChangesThis exposes the `eBroadcastBitSymbolChange` bit to the SB API to show when a symbol change event has been broadcast as this wasn't being done before. Also refactors `eBroadcastSymbolChange` to `eBroadcastBitSymbolChange` to match the naming convention for other event bits used in the debugger. -- Full diff: https://github.com//pull/66144.diff5 Files Affected:
diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index 29cf2c16fad4bd7..abb08e93d197a18 100644 --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -13,6 +13,7 @@ #include "lldb/API/SBDefines.h" #include "lldb/API/SBPlatform.h" +#include "lldb/API/SBStructuredData.h" namespace lldb_private { class CommandPluginInterfaceImplementation; @@ -46,6 +47,7 @@ class LLDB_API SBDebugger { eBroadcastBitProgress = (1 << 0), eBroadcastBitWarning = (1 << 1), eBroadcastBitError = (1 << 2), + eBroadcastBitSymbolChange = (1 << 3), }; SBDebugger(); diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index 5532cace606bfed..6cdf1a183b18e54 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -83,7 +83,7 @@ class Debugger : public std::enable_shared_from_this<Debugger>, eBroadcastBitProgress = (1 << 0), eBroadcastBitWarning = (1 << 1), eBroadcastBitError = (1 << 2), - eBroadcastSymbolChange = (1 << 3), + eBroadcastBitSymbolChange = (1 << 3), }; using DebuggerList = std::vector<lldb::DebuggerSP>; diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index 3e024ff91b382d7..8051b3826294ab3 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -4504,6 +4504,10 @@ class CommandObjectTargetSymbolsAdd : public CommandObjectParsed { if (process) process->Flush(); } + + if (result.Succeeded()) + Debugger::ReportSymbolChange(module_spec); + return result.Succeeded(); } diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 7ec1efc64fe9383..924741f45040bf0 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -1536,7 +1536,7 @@ void Debugger::ReportSymbolChange(const ModuleSpec &module_spec) { std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); for (DebuggerSP debugger_sp : *g_debugger_list_ptr) { EventSP event_sp = std::make_shared<Event>( - Debugger::eBroadcastSymbolChange, + Debugger::eBroadcastBitSymbolChange, new SymbolChangeEventData(debugger_sp, module_spec)); debugger_sp->GetBroadcaster().BroadcastEvent(event_sp); } @@ -1844,7 +1844,7 @@ lldb::thread_result_t Debugger::DefaultEventHandler() { listener_sp->StartListeningForEvents( &m_broadcaster, eBroadcastBitProgress | eBroadcastBitWarning | - eBroadcastBitError | eBroadcastSymbolChange); + eBroadcastBitError | eBroadcastBitSymbolChange); // Let the thread that spawned us know that we have started up and that we // are now listening to all required events so no events get missed diff --git a/lldb/test/API/commands/add-dsym/uuid/TestAddDsymCommand.py b/lldb/test/API/commands/add-dsym/uuid/TestAddDsymCommand.py index d16ca32d79e6808..1d7caf3122dcccb 100644 --- a/lldb/test/API/commands/add-dsym/uuid/TestAddDsymCommand.py +++ b/lldb/test/API/commands/add-dsym/uuid/TestAddDsymCommand.py @@ -57,6 +57,30 @@ def test_add_dsym_with_dSYM_bundle(self): self.exe_name = "a.out" self.do_add_dsym_with_dSYM_bundle(self.exe_name) + @no_debug_info_test + def test_report_symbol_change(self): + """Test that when adding a symbol file, the eBroadcastBitSymbolChange event gets broadcasted.""" + self.generate_main_cpp(version=1) + self.build(debug_info="dsym") + + self.exe_name = "a.out" + + # Get the broadcaster and listen for the symbol change event + self.broadcaster = self.dbg.GetBroadcaster() + self.listener = lldbutil.start_listening_from( + self.broadcaster, lldb.SBDebugger.eBroadcastBitSymbolChange + ) + + # Add the dSYM + self.do_add_dsym_with_success(self.exe_name) + + # Get the next event + event = lldbutil.fetch_next_event(self, self.listener, self.broadcaster) + + # Check that the event is valid + self.assertTrue(event.IsValid(), "Got a valid event.") + + def generate_main_cpp(self, version=0): """Generate main.cpp from main.cpp.template.""" temp = os.path.join(self.getSourceDir(), self.template) |
This exposes the `eBroadcastBitSymbolChange` bit to the SB API to show when a symbol change event has been broadcast as this wasn't being done before. Also refactors `eBroadcastSymbolChange` to `eBroadcastBitSymbolChange` to match the naming convention for other event bits used in the debugger.
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.
We should be able to extract the SBModuleSpec from the event in response to the eBroadcastBitSymbolChange event. This will require adding a static method to SBDebugger.h/.cpp to get the SBModuleSpec from the event:
static lldb::SBModuleSpec
GetModuleSpecFromEvent(const lldb::SBEvent &event);
You are passing a module specification to the Debugger::ReportSymbolChange(), so it should be easy to package this into a custom event and extract the data. Plenty of example of extracting data from events in SBDebugger, SBTarget and SBProcess
lldb/include/lldb/Core/Debugger.h
Outdated
@@ -83,7 +83,7 @@ class Debugger : public std::enable_shared_from_this<Debugger>, | |||
eBroadcastBitProgress = (1 << 0), | |||
eBroadcastBitWarning = (1 << 1), | |||
eBroadcastBitError = (1 << 2), | |||
eBroadcastSymbolChange = (1 << 3), | |||
eBroadcastBitSymbolChange = (1 << 3), |
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 name led me to believe that a Symbol from a symbol table was changed, so it confused me just reading the code. Do we want this to be "eBroadcastBitSymbolFileAdded"?
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.
If we change the name of the broadcast bit, we should also rename the SymbolChangeEventData
.
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.
Should it be SymbolFileAdded
or SymbolFileChanged
? You can (re)load a symbol file, which is something I've done with the JSON symbol file format.
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.
Should it be
SymbolFileAdded
orSymbolFileChanged
? You can (re)load a symbol file, which is something I've done with the JSON symbol file format.
I am fine with any name as long as it is clear that this is a symbol file change. The previous name led me to think a new symbol showed up in some symbol table. Luckily this enum is private, so we can rename as needed. But we should get the name as we want it in the SBDebugger.h file since we can't rename that after releasing it in the public API.
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.
For clarity it can be renamed to eBroadcastBitSymbolFilesChanged
in Debugger.h since we should remove this flag from the public view.
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.
Yes, that's what Greg's suggesting 👍
PS: Probably just a typo, but it should be eBroadcastBitSymbolFileChanged
(instead of Files
).
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.
Yes, I mistyped but fixed the typo in the fixup commit.
lldb/include/lldb/API/SBDebugger.h
Outdated
@@ -46,6 +47,7 @@ class LLDB_API SBDebugger { | |||
eBroadcastBitProgress = (1 << 0), | |||
eBroadcastBitWarning = (1 << 1), | |||
eBroadcastBitError = (1 << 2), | |||
eBroadcastBitSymbolChange = (1 << 3), |
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 comment below about possible name change to "eBroadcastBitSymbolFileAdded"
lldb/include/lldb/API/SBDebugger.h
Outdated
@@ -13,6 +13,7 @@ | |||
|
|||
#include "lldb/API/SBDefines.h" | |||
#include "lldb/API/SBPlatform.h" | |||
#include "lldb/API/SBStructuredData.h" |
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 isn't needed in the header file right? Move to SBDebugger.cpp if it is still needed? No mention of SBStructuredData in SBDebugger.h
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.
Correct, I left this in here by mistake.
1a544b9
to
8754d93
Compare
Okay, here's my understanding of what's going on here: So what's going on here is that in order to support background fetching of dSYM's, there's a thread that calls dsymForUUID when someone tells it there's a binary with an unknown UUID, then when it gets the dSYM it needs to notify the system that the symbols for this module have changed. It was inconvenient to call the Target::SymbolsDidLoad for all the targets from the background thread, so we instead made an event (eBroadcastSymbolChange, should be eBroadcastBitSymbolChange) whose whole reason for being is that its DoOnRemoval is the one that calls Target::SymbolsDidLoad, and then we can make a Listener that just polls continuously for this event. It is just pulling and discarding the event to cause SymbolsDidLoad, so it is really an internal event, it should not be exposed to other clients. Instead, what will happen is that when the Debugger::eBroadcastBitSymbolChange event gets pulled from the event queue, it will run through the targets and call their SymbolsDidLoad if they have the UUID that just got loaded. Target::SymbolsDidLoad will in turn broadcast a Target::eBroadcastBitSymbolsLoaded event, that's the public one, and is correctly going to the Target's involved. I think the only things that need doing here are:
Note, Jonas already added the Target::eBroadcastBitSymbolsChanged, but it wasn't getting dispatched because we didn't remember to tell ourselves the difference between Loaded and Changed. |
This should be documented in the Debugger.h header file next to the enum value to ensure. Might be good idea to start private event bits that never will go public at bit 31 and use the high bits of the bitfield so if we ever add a new event that will go into the public API, we don't have gaps. Though we can easily just change the internal bit if/when needed to not conflict with a new bit that might go public
Does this API work for eBroadcastBitSymbolsLoaded:
?
Fine with either adding or overloading this. I would be nice if the SBTarget::GetModuleAtIndexFromEvent() works for both of these? |
lldb/include/lldb/API/SBDebugger.h
Outdated
@@ -46,6 +47,7 @@ class LLDB_API SBDebugger { | |||
eBroadcastBitProgress = (1 << 0), | |||
eBroadcastBitWarning = (1 << 1), | |||
eBroadcastBitError = (1 << 2), | |||
eBroadcastBitSymbolChange = (1 << 3), |
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.
Sounds like this shouldn't be public per Jim's comments as the one from Debugger.h is designed to be private
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.
Yes, as per Jim's comments this shouldn't be exposed anymore and clients should use the Target::eBroadcastBitSymbolsLoaded/Changed
bits instead. Target::eBroadcastBitSymbolsChanged
is in the Target
header file but isn't exposed through the SB API and isn't sent using an event broadcast.
lldb/include/lldb/Core/Debugger.h
Outdated
@@ -83,7 +83,7 @@ class Debugger : public std::enable_shared_from_this<Debugger>, | |||
eBroadcastBitProgress = (1 << 0), | |||
eBroadcastBitWarning = (1 << 1), | |||
eBroadcastBitError = (1 << 2), | |||
eBroadcastSymbolChange = (1 << 3), | |||
eBroadcastBitSymbolChange = (1 << 3), |
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.
Per Jim's comments this should be a private event bit that we don't want exposed in the public API. Best to rename to contain the work "Private" and possibly use bit 31:
eBroadcastBitPrivateSymbolChange = (1 << 31),
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.
Would we want to both remove the bit from the SB API and use the higher-order bits for private events bits like this?
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.
Yes, the SB API is public, so it shouldn't be there if it's private.
lldb/source/Target/Target.cpp
Outdated
@@ -66,6 +66,7 @@ | |||
#include "llvm/ADT/ScopeExit.h" | |||
#include "llvm/ADT/SetVector.h" | |||
|
|||
#include <_types/_uint32_t.h> |
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 was included by mistake
I can add this to the test as adding the bit shouldn't have changed the event_data. |
lldb/include/lldb/Core/Debugger.h
Outdated
@@ -83,7 +83,7 @@ class Debugger : public std::enable_shared_from_this<Debugger>, | |||
eBroadcastBitProgress = (1 << 0), | |||
eBroadcastBitWarning = (1 << 1), | |||
eBroadcastBitError = (1 << 2), | |||
eBroadcastSymbolChange = (1 << 3), | |||
eBroadcastBitSymbolFileChange = (1 << 3), |
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.
eBroadcastBitSymbolFileChanged? Add a 'd'?
listener.WaitForEvent(1, event) | ||
|
||
# Check that the event is valid | ||
self.assertTrue(event.IsValid(), "Got a valid eBroadcastBitSymbolsLoaded event.") |
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.
Can we test that we can extract the SBModuleSpec for the module that changed from this event?
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.
We can get the SBModules from the event using SBTarget::GetModuleAtIndexFromEvent
and SBTarget::GetNumModulesFromEvent
, unfortunately there's no way to get an SBModuleSpec from an SBModule.
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.
We can get the SBModules from the event using
SBTarget::GetModuleAtIndexFromEvent
andSBTarget::GetNumModulesFromEvent
, unfortunately there's no way to get an SBModuleSpec from an SBModule.
SBModule is fine!
Refactors `eBroadcastBitSymbolChange` to `eBroadcastBitSymbolChanged`
This provides a test to ensure that when modules are loaded via the
add-dsym
command that they're loaded properly and broadcast theTarget::eBroadcastBitSymbolsLoaded
bit.Also refactors
Debugger::eBroadcastSymbolChange
toDebugger::eBroadcastBitSymbolChanged
to match the naming convention for other event bits used in the debugger.