diff -Naur gdb-7.4.1.orig/gdb/linux-nat.c gdb-7.4.1/gdb/linux-nat.c
--- gdb-7.4.1.orig/gdb/linux-nat.c	2012-05-07 11:23:53.000000000 -0400
+++ gdb-7.4.1/gdb/linux-nat.c	2012-05-07 11:26:01.000000000 -0400
@@ -5665,8 +5665,8 @@
 linux_nat_close (int quitting)
 {
   /* Unregister from the event loop.  */
-  if (target_is_async_p ())
-    target_async (NULL, 0);
+  if (linux_nat_is_async_p ())
+    linux_nat_async (NULL, 0);
 
   if (linux_ops->to_close)
     linux_ops->to_close (quitting);
diff -Naur gdb-7.4.1.orig/gdb/target.c gdb-7.4.1/gdb/target.c
--- gdb-7.4.1.orig/gdb/target.c	2012-05-07 11:23:54.000000000 -0400
+++ gdb-7.4.1/gdb/target.c	2012-05-07 11:26:01.000000000 -0400
@@ -1010,16 +1010,10 @@
 	break;
     }
 
+  /* If we don't find target_ops, quit.  Only open targets should be
+     closed.  */
   if ((*cur) == NULL)
-    return 0;			/* Didn't find target_ops, quit now.  */
-
-  /* NOTE: cagney/2003-12-06: In '94 the close call was made
-     unconditional by moving it to before the above check that the
-     target was in the target stack (something about "Change the way
-     pushing and popping of targets work to support target overlays
-     and inheritance").  This doesn't make much sense - only open
-     targets should be closed.  */
-  target_close (t, 0);
+    return 0;			
 
   /* Unchain the target.  */
   tmp = (*cur);
@@ -1028,6 +1022,11 @@
 
   update_current_target ();
 
+  /* Finally close the target.  Note we do this after unchaining, so
+     any target method calls from within the target_close
+     implementation don't end up in T anymore.  */
+  target_close (t, 0);
+
   return 1;
 }
 
