diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c
index 0f0404f013..09d5175d90 100644
--- a/gdb/aix-thread.c
+++ b/gdb/aix-thread.c
@@ -981,12 +981,12 @@ aix_thread_inferior_created (struct target_ops *ops, int from_tty)
 /* Detach from the process attached to by aix_thread_attach().  */
 
 static void
-aix_thread_detach (struct target_ops *ops, int from_tty)
+aix_thread_detach (struct target_ops *ops, inferior *inf, int from_tty)
 {
   struct target_ops *beneath = find_target_beneath (ops);
 
   pd_disable ();
-  beneath->to_detach (beneath, from_tty);
+  beneath->to_detach (beneath, inf, from_tty);
 }
 
 /* Tell the inferior process to continue running thread PID if != -1
diff --git a/gdb/corefile.c b/gdb/corefile.c
index c5e4f91a07..abf9ea675d 100644
--- a/gdb/corefile.c
+++ b/gdb/corefile.c
@@ -68,7 +68,7 @@ core_file_command (const char *filename, int from_tty)
   gdb_assert (core_target != NULL);
 
   if (!filename)
-    (core_target->to_detach) (core_target, from_tty);
+    (core_target->to_detach) (core_target, current_inferior (), from_tty);
   else
     (core_target->to_open) (filename, from_tty);
 }
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 250f46aa05..190f0162d9 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -464,7 +464,7 @@ core_open (const char *arg, int from_tty)
 }
 
 static void
-core_detach (struct target_ops *ops, int from_tty)
+core_detach (struct target_ops *ops, inferior *inf, int from_tty)
 {
   unpush_target (ops);
   reinit_frame_cache ();
diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c
index 1441a6ad6d..7a862cdeae 100644
--- a/gdb/darwin-nat.c
+++ b/gdb/darwin-nat.c
@@ -1938,10 +1938,9 @@ darwin_attach (struct target_ops *ops, const char *args, int from_tty)
    previously attached.  It *might* work if the program was
    started via fork.  */
 static void
-darwin_detach (struct target_ops *ops, int from_tty)
+darwin_detach (struct target_ops *ops, inferior *inf, int from_tty)
 {
   pid_t pid = ptid_get_pid (inferior_ptid);
-  struct inferior *inf = current_inferior ();
   darwin_inferior *priv = get_darwin_inferior (inf);
   kern_return_t kret;
   int res;
diff --git a/gdb/gnu-nat.c b/gdb/gnu-nat.c
index 0debb02ee6..8271565a04 100644
--- a/gdb/gnu-nat.c
+++ b/gdb/gnu-nat.c
@@ -2255,7 +2255,7 @@ gnu_attach (struct target_ops *ops, const char *args, int from_tty)
    previously attached.  It *might* work if the program was
    started via fork.  */
 static void
-gnu_detach (struct target_ops *ops, int from_tty)
+gnu_detach (struct target_ops *ops, inferior *inf, int from_tty)
 {
   int pid;
 
diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c
index 44216c45d6..aa8b17f41a 100644
--- a/gdb/inf-ptrace.c
+++ b/gdb/inf-ptrace.c
@@ -244,7 +244,7 @@ inf_ptrace_post_attach (struct target_ops *self, int pid)
 /* Detach from the inferior.  If FROM_TTY is non-zero, be chatty about it.  */
 
 static void
-inf_ptrace_detach (struct target_ops *ops, int from_tty)
+inf_ptrace_detach (struct target_ops *ops, inferior *inf, int from_tty)
 {
   pid_t pid = ptid_get_pid (inferior_ptid);
 
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 8865244fd9..4ad37aa275 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -2976,7 +2976,7 @@ detach_command (const char *args, int from_tty)
 
   disconnect_tracing ();
 
-  target_detach (from_tty);
+  target_detach (current_inferior (), from_tty);
 
   /* The current inferior process was just detached successfully.  Get
      rid of breakpoints that no longer make sense.  Note we don't do
diff --git a/gdb/infrun.c b/gdb/infrun.c
index d240208172..45fe36a717 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -606,7 +606,7 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
 				target_pid_to_str (process_ptid));
 	    }
 
-	  target_detach (0);
+	  target_detach (parent_inf, 0);
 	}
 
       /* Note that the detach above makes PARENT_INF dangling.  */
@@ -976,7 +976,7 @@ handle_vfork_child_exec_or_exit (int exec)
 		}
 	    }
 
-	  target_detach (0);
+	  target_detach (inf->vfork_parent, 0);
 
 	  /* Put it back.  */
 	  inf->pspace = pspace;
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 99d12f2526..70f4c084dc 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -1497,7 +1497,7 @@ detach_callback (struct lwp_info *lp, void *data)
 }
 
 static void
-linux_nat_detach (struct target_ops *ops, int from_tty)
+linux_nat_detach (struct target_ops *ops, inferior *inf, int from_tty)
 {
   int pid;
   struct lwp_info *main_lwp;
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c
index 9dcfc0e98b..873f929144 100644
--- a/gdb/linux-thread-db.c
+++ b/gdb/linux-thread-db.c
@@ -1090,13 +1090,13 @@ record_thread (struct thread_db_info *info,
 }
 
 static void
-thread_db_detach (struct target_ops *ops, int from_tty)
+thread_db_detach (struct target_ops *ops, inferior *inf, int from_tty)
 {
   struct target_ops *target_beneath = find_target_beneath (ops);
 
   delete_thread_db_info (ptid_get_pid (inferior_ptid));
 
-  target_beneath->to_detach (target_beneath, from_tty);
+  target_beneath->to_detach (target_beneath, inf, from_tty);
 
   /* NOTE: From this point on, inferior_ptid is null_ptid.  */
 
diff --git a/gdb/nto-procfs.c b/gdb/nto-procfs.c
index 2fd2dcf79a..6408c21799 100644
--- a/gdb/nto-procfs.c
+++ b/gdb/nto-procfs.c
@@ -943,7 +943,7 @@ procfs_xfer_partial (struct target_ops *ops, enum target_object object,
    on signals, etc.  We'd better not have left any breakpoints
    in the program or it'll die when it hits one.  */
 static void
-procfs_detach (struct target_ops *ops, int from_tty)
+procfs_detach (struct target_ops *ops, inferior *inf, int from_tty)
 {
   int pid;
 
diff --git a/gdb/procfs.c b/gdb/procfs.c
index 491970a787..2d5ec65c9b 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -1924,7 +1924,7 @@ procfs_attach (struct target_ops *ops, const char *args, int from_tty)
 }
 
 static void
-procfs_detach (struct target_ops *ops, int from_tty)
+procfs_detach (struct target_ops *ops, inferior *inf, int from_tty)
 {
   int pid = ptid_get_pid (inferior_ptid);
 
diff --git a/gdb/record.c b/gdb/record.c
index 74a14dc07b..9a476142e9 100644
--- a/gdb/record.c
+++ b/gdb/record.c
@@ -187,7 +187,7 @@ record_disconnect (struct target_ops *t, const char *args, int from_tty)
 /* See record.h.  */
 
 void
-record_detach (struct target_ops *t, int from_tty)
+record_detach (struct target_ops *t, inferior *inf, int from_tty)
 {
   gdb_assert (t->to_stratum == record_stratum);
 
@@ -196,7 +196,7 @@ record_detach (struct target_ops *t, int from_tty)
   record_stop (t);
   record_unpush (t);
 
-  target_detach (from_tty);
+  target_detach (inf, from_tty);
 }
 
 /* See record.h.  */
diff --git a/gdb/record.h b/gdb/record.h
index a0ca84dff3..21fafeba82 100644
--- a/gdb/record.h
+++ b/gdb/record.h
@@ -24,6 +24,7 @@
 #include "common/enum-flags.h"
 
 struct cmd_list_element;
+struct inferior;
 
 extern unsigned int record_debug;
 
@@ -88,7 +89,7 @@ extern void record_goto (const char *arg);
 extern void record_disconnect (struct target_ops *, const char *, int);
 
 /* The default "to_detach" target method for record targets.  */
-extern void record_detach (struct target_ops *, int);
+extern void record_detach (struct target_ops *, inferior *, int);
 
 /* The default "to_mourn_inferior" target method for record targets.  */
 extern void record_mourn_inferior (struct target_ops *);
diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c
index edc70d5b3e..aed7a34b42 100644
--- a/gdb/remote-sim.c
+++ b/gdb/remote-sim.c
@@ -77,7 +77,7 @@ static void gdbsim_open (const char *args, int from_tty);
 
 static void gdbsim_close (struct target_ops *self);
 
-static void gdbsim_detach (struct target_ops *ops, int from_tty);
+static void gdbsim_detach (struct target_ops *ops, inferior *inf, int from_tty);
 
 static void gdbsim_prepare_to_store (struct target_ops *self,
 				     struct regcache *regcache);
@@ -820,7 +820,7 @@ gdbsim_close (struct target_ops *self)
    Use this when you want to detach and do something else with your gdb.  */
 
 static void
-gdbsim_detach (struct target_ops *ops, int from_tty)
+gdbsim_detach (struct target_ops *ops, inferior *inf, int from_tty)
 {
   if (remote_debug)
     fprintf_unfiltered (gdb_stdlog, "gdbsim_detach\n");
diff --git a/gdb/remote.c b/gdb/remote.c
index 01b236fcd3..5ac84df0a0 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -5126,7 +5126,7 @@ remote_detach_pid (int pid)
    one.  */
 
 static void
-remote_detach_1 (int from_tty)
+remote_detach_1 (int from_tty, inferior *inf)
 {
   int pid = ptid_get_pid (inferior_ptid);
   struct remote_state *rs = get_remote_state ();
@@ -5162,15 +5162,15 @@ remote_detach_1 (int from_tty)
 }
 
 static void
-remote_detach (struct target_ops *ops, int from_tty)
+remote_detach (struct target_ops *ops, inferior *inf, int from_tty)
 {
-  remote_detach_1 (from_tty);
+  remote_detach_1 (from_tty, inf);
 }
 
 static void
-extended_remote_detach (struct target_ops *ops, int from_tty)
+extended_remote_detach (struct target_ops *ops, inferior *inf, int from_tty)
 {
-  remote_detach_1 (from_tty);
+  remote_detach_1 (from_tty, inf);
 }
 
 /* Target follow-fork function for remote targets.  On entry, and
diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c
index e724c7e0fa..2c7dd0e15d 100644
--- a/gdb/sol-thread.c
+++ b/gdb/sol-thread.c
@@ -348,14 +348,14 @@ lwp_to_thread (ptid_t lwp)
    program was started via the normal ptrace (PTRACE_TRACEME).  */
 
 static void
-sol_thread_detach (struct target_ops *ops, int from_tty)
+sol_thread_detach (struct target_ops *ops, inferior *inf, int from_tty)
 {
   struct target_ops *beneath = find_target_beneath (ops);
 
   sol_thread_active = 0;
   inferior_ptid = pid_to_ptid (ptid_get_pid (main_ph.ptid));
   unpush_target (ops);
-  beneath->to_detach (beneath, from_tty);
+  beneath->to_detach (beneath, inf, from_tty);
 }
 
 /* Resume execution of process PTID.  If STEP is nozero, then just
diff --git a/gdb/target-debug.h b/gdb/target-debug.h
index d7d99eff5d..d7fc001975 100644
--- a/gdb/target-debug.h
+++ b/gdb/target-debug.h
@@ -170,6 +170,8 @@
   target_debug_do_print (host_address_to_string (X.get ()))
 #define target_debug_print_gdb_array_view_const_int(X)	\
   target_debug_do_print (host_address_to_string (X.data ()))
+#define target_debug_print_inferior_p(inf) \
+  target_debug_do_print (host_address_to_string (inf))
 
 static void
 target_debug_print_struct_target_waitstatus_p (struct target_waitstatus *status)
diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c
index 6bb7d7fba7..bc847916b4 100644
--- a/gdb/target-delegates.c
+++ b/gdb/target-delegates.c
@@ -28,26 +28,28 @@ debug_post_attach (struct target_ops *self, int arg1)
 }
 
 static void
-delegate_detach (struct target_ops *self, int arg1)
+delegate_detach (struct target_ops *self, inferior *arg1, int arg2)
 {
   self = self->beneath;
-  self->to_detach (self, arg1);
+  self->to_detach (self, arg1, arg2);
 }
 
 static void
-tdefault_detach (struct target_ops *self, int arg1)
+tdefault_detach (struct target_ops *self, inferior *arg1, int arg2)
 {
 }
 
 static void
-debug_detach (struct target_ops *self, int arg1)
+debug_detach (struct target_ops *self, inferior *arg1, int arg2)
 {
   fprintf_unfiltered (gdb_stdlog, "-> %s->to_detach (...)\n", debug_target.to_shortname);
-  debug_target.to_detach (&debug_target, arg1);
+  debug_target.to_detach (&debug_target, arg1, arg2);
   fprintf_unfiltered (gdb_stdlog, "<- %s->to_detach (", debug_target.to_shortname);
   target_debug_print_struct_target_ops_p (&debug_target);
   fputs_unfiltered (", ", gdb_stdlog);
-  target_debug_print_int (arg1);
+  target_debug_print_inferior_p (arg1);
+  fputs_unfiltered (", ", gdb_stdlog);
+  target_debug_print_int (arg2);
   fputs_unfiltered (")\n", gdb_stdlog);
 }
 
diff --git a/gdb/target.c b/gdb/target.c
index b01e1ac645..ce630f43de 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -2108,7 +2108,7 @@ dispose_inferior (struct inferior *inf, void *args)
       if (target_has_execution)
 	target_kill ();
       else
-	target_detach (0);
+	target_detach (inf, 0);
     }
 
   return 0;
@@ -2144,8 +2144,15 @@ target_preopen (int from_tty)
 /* See target.h.  */
 
 void
-target_detach (int from_tty)
+target_detach (inferior *inf, int from_tty)
 {
+  /* As long as some to_detach implementations rely on the current_inferior
+     (either directly, or indirectly, like through target_gdbarch or by
+     reading memory), INF needs to be the current inferior.  When that
+     requirement will become no longer true, then we can remove this
+     assertion.  */
+  gdb_assert (inf == current_inferior ());
+
   if (gdbarch_has_global_breakpoints (target_gdbarch ()))
     /* Don't remove global breakpoints here.  They're removed on
        disconnection from the target.  */
@@ -2157,7 +2164,7 @@ target_detach (int from_tty)
 
   prepare_for_detach ();
 
-  current_target.to_detach (&current_target, from_tty);
+  current_target.to_detach (&current_target, inf, from_tty);
 }
 
 void
diff --git a/gdb/target.h b/gdb/target.h
index 51841a1cbb..52361baa36 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -440,7 +440,7 @@ struct target_ops
     void (*to_attach) (struct target_ops *ops, const char *, int);
     void (*to_post_attach) (struct target_ops *, int)
       TARGET_DEFAULT_IGNORE ();
-    void (*to_detach) (struct target_ops *ops, int)
+    void (*to_detach) (struct target_ops *ops, inferior *, int)
       TARGET_DEFAULT_IGNORE ();
     void (*to_disconnect) (struct target_ops *, const char *, int)
       TARGET_DEFAULT_NORETURN (tcomplain ());
@@ -1326,7 +1326,7 @@ extern void target_announce_detach (int from_tty);
    in the program or it'll die when it hits one.  FROM_TTY says whether to be
    verbose or not.  */
 
-extern void target_detach (int from_tty);
+extern void target_detach (inferior *inf, int from_tty);
 
 /* Disconnect from the current target without resuming it (leaving it
    waiting for a debugger).  */
diff --git a/gdb/top.c b/gdb/top.c
index 1e6d5137b8..a6166bd280 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -1485,7 +1485,7 @@ kill_or_detach (struct inferior *inf, void *args)
       if (target_has_execution)
 	{
 	  if (inf->attach_flag)
-	    target_detach (qt->from_tty);
+	    target_detach (inf, qt->from_tty);
 	  else
 	    target_kill ();
 	}
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 4023089a4d..5fb143e00d 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -1931,7 +1931,7 @@ windows_attach (struct target_ops *ops, const char *args, int from_tty)
 }
 
 static void
-windows_detach (struct target_ops *ops, int from_tty)
+windows_detach (struct target_ops *ops, inferior *inf, int from_tty)
 {
   int detached = 1;
 
