diff --git a/gdb/remote.c b/gdb/remote.c
index 4e65092..224a520 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -1477,6 +1477,46 @@ remote_vfork_event_p (struct remote_state *rs)
   return packet_support (PACKET_vfork_event_feature) == PACKET_ENABLE;
 }
 
+/* Insert fork catchpoint target routine.  If fork events are enabled
+   then return success, nothing more to do.  */
+
+static int
+remote_insert_fork_catchpoint (struct target_ops *ops, int pid)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  return !remote_fork_event_p (rs);
+}
+
+/* Remove fork catchpoint target routine.  Nothing to do, just
+   return success.  */
+
+static int
+remote_remove_fork_catchpoint (struct target_ops *ops, int pid)
+{
+  return 0;
+}
+
+/* Insert vfork catchpoint target routine.  If vfork events are enabled
+   then return success, nothing more to do.  */
+
+static int
+remote_insert_vfork_catchpoint (struct target_ops *ops, int pid)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  return !remote_vfork_event_p (rs);
+}
+
+/* Remove vfork catchpoint target routine.  Nothing to do, just
+   return success.  */
+
+static int
+remote_remove_vfork_catchpoint (struct target_ops *ops, int pid)
+{
+  return 0;
+}
+
 /* Tokens for use by the asynchronous signal handlers for SIGINT.  */
 static struct async_signal_handler *async_sigint_remote_twice_token;
 static struct async_signal_handler *async_sigint_remote_token;
@@ -2815,6 +2855,56 @@ remote_get_threads_with_qthreadinfo (struct target_ops *ops,
   return 0;
 }
 
+/* Determine if THREAD is a pending fork parent thread.  ARG contains
+   the pid of the process who's threads we want to check, or -1 if
+   we want to check all threads.  */
+
+static int
+pending_fork_parent_callback (struct thread_info *thread, void *arg)
+{
+  int pid = *(int *) arg;
+
+  if (thread->pending_follow.kind == TARGET_WAITKIND_FORKED
+      || thread->pending_follow.kind == TARGET_WAITKIND_VFORKED)
+    {
+      if ((pid == -1) || (pid == ptid_get_pid (thread->ptid)))
+	return 1;
+    }
+
+  return 0;
+}
+
+/* If CONTEXT contains any fork child threads that have not been
+   reported yet, remove them from the CONTEXT list.  If such a
+   thread exists it is because we are stopped at a fork catchpoint
+   and have not yet called follow_fork, which will set up the
+   host-side data structures for the new process.  */
+
+static void
+remove_new_fork_child (struct threads_listing_context *context)
+{
+  struct thread_info * thread;
+  int pid = -1;
+
+  /* Check to see if there is an in-progress fork parent.  */
+  thread = iterate_over_threads (pending_fork_parent_callback, &pid);
+  if (thread != NULL)
+    {
+      ptid_t child_ptid = thread->pending_follow.value.related_pid;
+      struct thread_item *item;
+      int i;
+
+      for (i = 0; VEC_iterate (thread_item_t, context->items, i, item); ++i)
+	{
+	  if (ptid_equal (item->ptid, child_ptid))
+	    {
+	      VEC_ordered_remove (thread_item_t, context->items, i);
+	      break;
+	    }
+	}
+    }
+}
+
 /* Implement the to_update_thread_list function for the remote
    targets.  */
 
@@ -2874,6 +2964,10 @@ remote_update_thread_list (struct target_ops *ops)
 	    }
         }
 
+      /* Remove any unreported fork child from CONTEXT so that
+	 we don't interfere with follow fork.  */
+      remove_new_fork_child (&context);
+
       /* And now add threads we don't know about yet to our list.  */
       for (i = 0;
 	   VEC_iterate (thread_item_t, context.items, i, item);
@@ -7998,6 +8092,21 @@ extended_remote_kill (struct target_ops *ops)
   int res;
   int pid = ptid_get_pid (inferior_ptid);
   struct remote_state *rs = get_remote_state ();
+  struct thread_info *thread;
+
+  /* If we're stopped while forking and we haven't followed yet,
+     kill the child task.  We need to do this first because the
+     parent will be sleeping if this is a vfork.  */
+  thread = iterate_over_threads (pending_fork_parent_callback, &pid);
+  if (thread != NULL)
+    {
+      int child_pid;
+
+      child_pid = ptid_get_pid (thread->pending_follow.value.related_pid);
+      res = remote_vkill (child_pid, rs);
+      if (res != 0)
+	error (_("Can't kill fork child process"));
+    }
 
   res = remote_vkill (pid, rs);
   if (res == -1 && !(rs->extended && remote_multi_process_p (rs)))
@@ -11913,6 +12022,14 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
   extended_remote_ops.to_supports_disable_randomization
     = extended_remote_supports_disable_randomization;
   extended_remote_ops.to_follow_fork = remote_follow_fork;
+  extended_remote_ops.to_insert_fork_catchpoint
+    = remote_insert_fork_catchpoint;
+  extended_remote_ops.to_remove_fork_catchpoint
+    = remote_remove_fork_catchpoint;
+  extended_remote_ops.to_insert_vfork_catchpoint
+    = remote_insert_vfork_catchpoint;
+  extended_remote_ops.to_remove_vfork_catchpoint
+    = remote_remove_vfork_catchpoint;
 }
 
 static int
