diff --git a/gdb/corefile.c b/gdb/corefile.c
index c27061a3ae3..19a96bc6f86 100644
--- a/gdb/corefile.c
+++ b/gdb/corefile.c
@@ -120,11 +120,6 @@ reopen_exec_file (void)
       && current_program_space->ebfd_mtime
       && current_program_space->ebfd_mtime != st.st_mtime)
     exec_file_attach (filename.c_str (), 0);
-  else
-    /* If we accessed the file since last opening it, close it now;
-       this stops GDB from holding the executable open after it
-       exits.  */
-    bfd_cache_close_all ();
 }
 
 /* If we have both a core file and an exec file,
diff --git a/gdb/event-top.c b/gdb/event-top.c
index 3d6fa896a9c..b8378f4e653 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -462,6 +462,22 @@ display_gdb_prompt (const char *new_prompt)
     }
 }
 
+/* Notify the 'before_prompt' observer, and run any additional actions
+   that must be done before we display the prompt.  */
+static void
+notify_before_prompt (const char *prompt)
+{
+  /* Give observers a chance of changing the prompt.  E.g., the python
+     `gdb.prompt_hook' is installed as an observer.  */
+  gdb::observers::before_prompt.notify (prompt);
+
+  /* As we are about to display the prompt, and so GDB might be sitting
+     idle for some time, close all the cached BFDs.  This ensures that
+     when we next start running a user command all BFDs will be reopened
+     as needed, and as a result, we will see any on-disk changes.  */
+  bfd_cache_close_all ();
+}
+
 /* Return the top level prompt, as specified by "set prompt", possibly
    overridden by the python gdb.prompt_hook hook, and then composed
    with the prompt prefix and suffix (annotations).  */
@@ -469,9 +485,7 @@ display_gdb_prompt (const char *new_prompt)
 static std::string
 top_level_prompt (void)
 {
-  /* Give observers a chance of changing the prompt.  E.g., the python
-     `gdb.prompt_hook' is installed as an observer.  */
-  gdb::observers::before_prompt.notify (get_prompt ().c_str ());
+  notify_before_prompt (get_prompt ().c_str ());
 
   const std::string &prompt = get_prompt ();
 
diff --git a/gdb/exec.c b/gdb/exec.c
index 5956012338f..59965b84d55 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -500,8 +500,6 @@ exec_file_attach (const char *filename, int from_tty)
 	(*deprecated_exec_file_display_hook) (filename);
     }
 
-  bfd_cache_close_all ();
-
   /* Are are loading the same executable?  */
   bfd *prev_bfd = exec_bfd_holder.get ();
   bfd *curr_bfd = current_program_space->exec_bfd ();
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index cf8cd527955..5153843dde8 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -2498,7 +2498,6 @@ kill_command (const char *arg, int from_tty)
   int infnum = current_inferior ()->num;
 
   target_kill ();
-  bfd_cache_close_all ();
 
   update_previous_thread ();
 
diff --git a/gdb/inferior.c b/gdb/inferior.c
index 1778723863e..927c5f16ae2 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -714,8 +714,6 @@ kill_inferior_command (const char *args, int from_tty)
 
       target_kill ();
     }
-
-  bfd_cache_close_all ();
 }
 
 /* See inferior.h.  */
diff --git a/gdb/symfile.c b/gdb/symfile.c
index eebc5ea44b9..24570372316 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1124,7 +1124,6 @@ symbol_file_add_with_addrs (const gdb_bfd_ref_ptr &abfd, const char *name,
 
   gdb::observers::new_objfile.notify (objfile);
 
-  bfd_cache_close_all ();
   return objfile;
 }
 
diff --git a/gdb/target.c b/gdb/target.c
index f688ff33e3b..aeb53dd91d0 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -2729,11 +2729,6 @@ target_mourn_inferior (ptid_t ptid)
 {
   gdb_assert (ptid.pid () == inferior_ptid.pid ());
   current_inferior ()->top_target ()->mourn_inferior ();
-
-  /* We no longer need to keep handles on any of the object files.
-     Make sure to release them to avoid unnecessarily locking any
-     of them while we're not actually debugging.  */
-  bfd_cache_close_all ();
 }
 
 /* Look for a target which can describe architectural features, starting
diff --git a/gdb/thread.c b/gdb/thread.c
index c8145da59bc..a1e003b082e 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -876,6 +876,11 @@ notify_target_resumed (ptid_t ptid)
 {
   interps_notify_target_resumed (ptid);
   gdb::observers::target_resumed.notify (ptid);
+
+  /* We are about to resume the inferior.  Close all cached BFDs so that
+     when the inferior next stops, and GDB regains control, we will spot
+     any on-disk changes to the BFDs we are using.  */
+  bfd_cache_close_all ();
 }
 
 /* See gdbthread.h.  */
