You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
When debugging multiple inferiors with gdb, if one inferior exits the full debug session stops #1618
When running gdb with the same configuration via commandline everything works correctly. Execution pauses after the child exits, and then one can use inferior <id> to switch back to the parent and keep debugging.
Here is claude's suggestion for a fix, whether you decide to take that road or do something else I leave that up to the experts.
The teardown comes from MIEngine (the cppdbg adapter), not the extension's TypeScript: Debugger.OnStopped in src/MICore/Debugger.cs treats any *stopped,reason="exited*" as the end
of the debuggee and fires ProcessExitEvent, which sends -gdb-exit.
The record gdb emits when one inferior exits carries nothing that identifies which one:
=thread-exited,id="2",group-id="i2"
=thread-group-exited,id="i2",exit-code="0"
*stopped,reason="exited-normally"
But =thread-group-exited always arrives first, including in the single-inferior case — so by the time OnStopped runs, MIEngine's _debuggeePids is already empty for a real session
end and still non-empty for a mid-session inferior exit. That's an exact discriminator, and it leaves single-inferior sessions on the existing code path. MIEngine already has the
correct multi-inferior logic in HandleThreadGroupExited (it only synthesizes an exit when the last thread group is gone); the real *stopped record just bypasses it.
Two things the fix has to handle beyond skipping the teardown:
1. gdb leaves the exited inferior as the current one, so a plain -exec-continue — which is what CmdContinueAsync sends — fails with ^error,msg="The program is not being run."
Neither --all nor --thread scoping fixes the engine's later plain commands; the current thread has to be re-selected with -thread-select.
2. gdb has stopped every inferior (all-stop), so the engine must report a break rather than leaving the UI believing the debuggee is running.
With that, -thread-select 1 → -stack-info-frame → -exec-continue resumes cleanly and the breakpoint after the child's exit is hit, which is the expected behavior in the original
report.
Suggested shape (verified against gdb 17.1; reported on 16.3): in OnStopped's exit branch, if any thread group is still live and the debugger supports multiple inferiors, set
ProcessState = Stopped, pick a live thread from -thread-info, -thread-select it, and raise a new event that DebuggedProcess turns into _callback.OnAsyncBreakComplete(thread) — the
same callback the pause button uses. Gate -thread-select support on the gdb command factory so lldb-mi is untouched.
Activity
lostgoat commentedon Aug 19, 2026
Here is claude's suggestion for a fix, whether you decide to take that road or do something else I leave that up to the experts.