diff --git a/gdb/remote.c b/gdb/remote.c
index c0fa3b9..ec88afe 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,59 @@ 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 struct thread_info *
+is_pending_fork_parent (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 thread;
+    }
+
+  return NULL;
+}
+
+/* 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;
+
+  /* For any in-progress fork parent threads, delete the corresponding
+     fork child threads from the CONTEXT list.  */
+  ALL_NON_EXITED_THREADS (thread)
+    {
+      if (is_pending_fork_parent (thread, &pid) != 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.  */
 
@@ -2839,6 +2932,7 @@ remote_update_thread_list (struct target_ops *ops)
       int i;
       struct thread_item *item;
       struct thread_info *tp, *tmp;
+      struct notif_client *notif = &notif_client_stop;
 
       got_list = 1;
 
@@ -2874,6 +2968,14 @@ remote_update_thread_list (struct target_ops *ops)
 	    }
         }
 
+      /* Remove any unreported fork child threads from CONTEXT so
+	 that we don't interfere with follow fork, which is where
+	 creation of such threads is handled.  We first call
+	 remote_notif_get_pending_events to make sure that we
+	 know about any pending (unreported) fork events.  */
+      remote_notif_get_pending_events (notif);
+      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);
@@ -8002,6 +8104,27 @@ 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;
+  struct notif_client *notif = &notif_client_stop;
+
+  /* If we're stopped while forking and we haven't followed yet, kill the
+     child task.  We need to do this before killing the parent task
+     because if this is a vfork then the parent will be sleeping.  First
+     we need to call remote_notif_get_pending_events to make sure that we
+     know about any pending (unreported) fork events.  */
+  remote_notif_get_pending_events (notif);
+  ALL_NON_EXITED_THREADS (thread)
+    {
+      if (is_pending_fork_parent(thread, &pid))
+	{
+	  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 %d"), child_pid);
+	}
+    }
 
   res = remote_vkill (pid, rs);
   if (res == -1 && !(rs->extended && remote_multi_process_p (rs)))
@@ -11917,6 +12040,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
