[PATCH 1/3] gdb: delete some unnecessary code from core_target::detach

Andrew Burgess
2026-03-30T15:31:43Z

This commit removes some unnecessary code from core_target::detach.

When a core_target is created the core BFD (m_core_bfd) is set, and
will never be NULL. The m_core_bfd remains set until either
core_target::detach or core_target::close is called.

The core_target::close function is only called when the refcount of a
core_target reaches zero, the core_target::close function deletes the
core_target, so we know that after calling core_target::close no other
core_target member functions will be called (as the core_target will
have been deleted).

The core_target::detach function is called as a result of calling
target_detach, which is called as a result of either the 'detach'
command, or the 'core-file' command (without passing a file name).

As a core_target is not shareable (see
process_stratum_target::is_shareable), once a core_target is detached,
its reference count will reduce to zero, and then it will be closed
and deleted.

What this means is that there is absolutely no way that a core_target
can ever be detached twice, not that such a thing would make much
sense, but it cannot happen.

Understanding this we can know that when core_target::detach is called
m_core_bfd will never be NULL, I've added an assert for this case.

Given this assert, if we look at core_target::clear_core, which
core_target::detach calls, we can see that exit_inferior will always
be called. If we look at exit_inferior (in inferior.c) we see that
the last two actions of that function are:

/* Clear the register cache and the frame cache. */
registers_changed ();
reinit_frame_cache ();

Which are also two of the last three actions of core_target::detach.
Clearly the calls in core_target::detach are redundant.

Just for good measure, if we look in target_detach, from where
core_target::detach will have been called, just before the function
returns we have:

registers_changed_ptid (proc_target, save_pid_ptid);
reinit_frame_cache ();

The registers_changed_ptid call is slightly more restrictive, only
clearing the register cache for the target being detached, but that
should be good enough -- I think exit_inferior could probably be
changed to call registers_changed_ptid for the inferior that exited,
but that's a problem for another day.

What this all tells me is that the registers_changed call and the
reinit_frame_cache call in core_target::detach are unnecessary, and
can be deleted, which is what this patch does.

There should be no user visible changes after this commit.
---
gdb/corelow.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/gdb/corelow.c b/gdb/corelow.c
index 954607134f4..216b4e70066 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -1239,6 +1239,13 @@ core_target_open (const char *arg, int from_tty)
void
core_target::detach (inferior *inf, int from_tty)
{
+ /* The core BFD is set when the core_target is created and attached to
+ the inferior. It is only cleared during detach or close. After
+ detaching the core target will be closed and deleted, so detach can
+ never be called twice. What this means is that detach will never be
+ called without the core BFD being set. */
+ gdb_assert (this->core_bfd () != nullptr);
+
/* Get rid of the core. Don't rely on core_target::close doing it,
because target_detach may be called with core_target's refcount > 1,
meaning core_target::close may not be called yet by the
@@ -1250,9 +1257,7 @@ core_target::detach (inferior *inf, int from_tty)
implementation deletes 'this'. */
inf->unpush_target (this);

- /* Clear the register cache and the frame cache. */
- registers_changed ();
- reinit_frame_cache ();
+ /* Inform the user. */
maybe_say_no_core_file_now (from_tty);
}

--
2.25.4