gdb: send library events during module load - #320
Merged
Conversation
When a module is mapped at runtime (e.g. LoadLibrary), the stub now requests a stop and replies with the "library" stop reason (T05thread:1;library:;). Clients such as IDA then re-read qXfer:libraries:read, diff the list, and fire LIB_LOADED events. - WindowsEmulator gains module_change_listeners, notified after load_image appends to emu.modules (the single mutation point) - GdbServer registers a listener for the session lifetime; module changes set a flag and request a stop via the existing _request_stop machinery - If a stop is already pending or the target is stopped, the flag makes the next stop reply carry library:; instead; it clears once reported - No qSupported change needed: the library stop reason is not gated by a feature string FreeLibrary remains a no-op so unload events cannot occur yet; the mechanism is direction-agnostic since clients diff the full list. Closes #319
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
Drive the `library:;` stop-reply field only from the module-change flag. Keeping the `kind == "library"` check as a second source repeated the event on every later `?` query, because `_stop_reason` still held the library stop. Access `module_change_listeners` directly, matching how the server reaches every other emulator attribute.
williballenthin
force-pushed
the
issue-319-gdb-library-events
branch
from
August 28, 2026 13:02
a5d1c28 to
680e733
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #319
When a module is mapped at runtime (for example by
LoadLibrary), the gdb stub requests a stop and replies with thelibrarystop reason (T05thread:1;library:;). Clients such as IDA then re-readqXfer:libraries:read, diff the list against what they knew, and fireLIB_LOADEDevents, so runtime-loaded DLLs appear in the Modules window without a manual refresh. This matches Windows gdbserver semantics: theLoadLibraryhandler completes fully (module mapped, PEB updated, return value written) before unicorn halts, and the client resumes on its own unless the user chose to suspend on library load.Changes
WindowsEmulatorgainsmodule_change_listeners, notified afterload_imageappends toemu.modules(the single mutation point for the module list). Listener errors are logged, never propagated into emulation.GdbServerregisters a listener for the session lifetime (added on client connect, removed inclose()). A module change sets_library_list_changedand requests a stop through the existing_request_stopmachinery._stop_replyappendslibrary:;from that flag alone and clears it, so the field can coalesce with another pending stop reason (a breakpoint reached in the same instruction) or with a dependency chain that maps several DLLs before the halt. One stop covers them all, because the client diffs the full list.?query from re-reporting an event the client already handled.qSupportedchange: thelibrarystop reason is not gated by a feature string, andqXfer:libraries:read+is already advertised.FreeLibrarydoes not unmap, so unload events cannot occur. The mechanism is direction-agnostic (clients diff the full list), soLIB_UNLOADEDworks if module removal is implemented later.doc/gdb.mdrecords both the new stop reason and this limitation.Testing
tests/test_gdb_compat.py: a module change requests alibrarystop and its reply carrieslibrary:;; the flag piggybacks on a breakpoint stop reply and is reported once; the listener is removed when the session closes.tests/test_gdb.py: end-to-end subprocess test that maps a module mid-run through a code hook, asserts theT05...library:;stop reply, finds the new DLL in the re-fetched library XML, and confirms the next stop does not repeat the event. Suppressing the notification makes this test time out, so it is not vacuous.tests/capa-testfilessubmodule.🤖 Generated with Claude Code