gdb/python: fix 'exited' event when GDB exits from core file debugging
This fixes an issue that was reported here:
https://inbox.sourceware.org/gdb-patches/v3x4md2dg6rflq35ymzwrmmqf5uaem5exrnlbsp5dmhph2vihy@lq22ncu774yu
After commit:
commit 3780b9993c973a2b68b496b80eddb820c0932cc0
Date: Fri Mar 27 11:29:07 2026 +0000
gdb: refactor core_target ::close and ::detach functions
it was observed that the Python 'exited' event was no longer being
emitted when debugging a core file, and then exiting GDB.
The problem is that, when GDB is exiting we eventually end up in
quit_force (in top.c), which calls kill_or_detach for every inferior.
In kill_or_detach we call either target_detach or target_kill, but
only for non-core file targets. For core file targets, neither of
these is called and kill_or_detach does nothing of interest.
After the call to kill_or_detach, we call inferior::pop_all_targets,
which calls inferior::pop_all_targets_above the dummy_stratum target,
which means popping all targets.
In inferior::pop_all_targets_above (in inferior.c), we call
switch_to_inferior_no_thread, which ensures the correct inferior is
selected, but makes it so that no thread is selected. Switching to no
thread sets inferior_ptid to null_ptid.
Now popping the core_target calls core_target::close, and within
core_target::close we currently check inferior_ptid in order to
determine if exit_core_file_inferior has already been called or not.
We only call exit_core_file_inferior if inferior_ptid is not
null_ptid, so in this case we will not call exit_core_file_inferior.
The only other place that exit_core_file_inferior can be called from
is core_target::detach, but remember we specifically avoided calling
target_detach earlier in kill_or_detach. This means that
exit_core_file_inferior ends up never being called.
It is exit_core_file_inferior that calls exit_inferior, and it is from
here that the Python 'exited' event is emitted.
I don't see any reason why kill_or_detach couldn't call target_detach
for a core file target, but I don't propose making that change in this
commit.
The check against inferior_ptid in core_target::close is clearly
incorrect, checking this requires that a suitable thread within the
inferior be selected, and that is not really a requirement for closing
a core_target. Instead, we can just check the inferior::pid field.
When we open a core_target we always set inferior::pid, even if we
just assign a fake CORELOW_PID value, so checking inferior::pid
against zero will tell us if the inferior has already been exited.
Fixing this check is enough to resolve the reported bug and ensure
that the 'exited' event is always emitted, which is why I don't
propose changing kill_or_detach in this commit.
An assert in core_target::exit_core_file_inferior has to go too for
the same reason, the assert is checking that a thread is currently
selected, and as discussed above, this is not always the case.
There's a new test which checks that the 'exited' event is emitted for
a core file debug session, a native debug session where the inferior
is started by GDB, and a native debug session where GDB attaches to an
already running inferior.
Only the core file case was broken before this commit, but more
testing is always a good thing.
Reviewed-By: Lancelot Six <lancelot.six@amd.com>
Approved-By: Pedro Alves <pedro@palves.net>
4 files changed