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

Message ID 42209ecb3032e7f55e2113c15613af11056ac8c8.1774884529.git.aburgess@redhat.com
State New
Headers
Series New Python events.corefile_changed API |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Test passed

Commit Message

Andrew Burgess March 30, 2026, 3:30 p.m. UTC
  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(-)
  

Patch

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);
 }