* target.h (TARGET_WNOHANG): New.
[deliverable/binutils-gdb.git] / gdb / remote.c
index 390924f4b54ed5e4bedab18a7d5419d0f374d21a..199120d553dc27f19e6bf4920d35a7038e792503 100644 (file)
@@ -111,7 +111,7 @@ static void remote_send (char **buf, long *sizeof_buf_p);
 
 static int readchar (int timeout);
 
-static void remote_kill (void);
+static void remote_kill (struct target_ops *ops);
 
 static int tohex (int nib);
 
@@ -992,6 +992,7 @@ enum {
   PACKET_vKill,
   PACKET_qXfer_siginfo_read,
   PACKET_qXfer_siginfo_write,
+  PACKET_qAttached,
   PACKET_MAX
 };
 
@@ -1118,18 +1119,66 @@ static ptid_t any_thread_ptid;
 static ptid_t general_thread;
 static ptid_t continue_thread;
 
+/* Find out if the stub attached to PID (and hence GDB should offer to
+   detach instead of killing it when bailing out).  */
+
+static int
+remote_query_attached (int pid)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  if (remote_protocol_packets[PACKET_qAttached].support == PACKET_DISABLE)
+    return 0;
+
+  if (remote_multi_process_p (rs))
+    sprintf (rs->buf, "qAttached:%x", pid);
+  else
+    sprintf (rs->buf, "qAttached");
+
+  putpkt (rs->buf);
+  getpkt (&rs->buf, &rs->buf_size, 0);
+
+  switch (packet_ok (rs->buf,
+                    &remote_protocol_packets[PACKET_qAttached]))
+    {
+    case PACKET_OK:
+      if (strcmp (rs->buf, "1") == 0)
+       return 1;
+      break;
+    case PACKET_ERROR:
+      warning (_("Remote failure reply: %s"), rs->buf);
+      break;
+    case PACKET_UNKNOWN:
+      break;
+    }
+
+  return 0;
+}
+
 /* Add PID to GDB's inferior table.  Since we can be connected to a
    remote system before before knowing about any inferior, mark the
-   target with execution when we find the first inferior.  */
+   target with execution when we find the first inferior.  If ATTACHED
+   is 1, then we had just attached to this inferior.  If it is 0, then
+   we just created this inferior.  If it is -1, then try querying the
+   remote stub to find out if it had attached to the inferior or
+   not.  */
 
 static struct inferior *
-remote_add_inferior (int pid)
+remote_add_inferior (int pid, int attached)
 {
   struct remote_state *rs = get_remote_state ();
   struct inferior *inf;
 
+  /* Check whether this process we're learning about is to be
+     considered attached, or if is to be considered to have been
+     spawned by the stub.  */
+  if (attached == -1)
+    attached = remote_query_attached (pid);
+
   inf = add_inferior (pid);
 
+  inf->attach_flag = attached;
+
   /* This may be the first inferior we hear about.  */
   if (!target_has_execution)
     {
@@ -1179,15 +1228,23 @@ remote_notice_new_inferior (ptid_t currthread, int running)
   if (!in_thread_list (currthread))
     {
       struct inferior *inf = NULL;
+      int pid = ptid_get_pid (currthread);
 
-      if (ptid_equal (pid_to_ptid (ptid_get_pid (currthread)), inferior_ptid))
+      if (ptid_is_pid (inferior_ptid)
+         && pid == ptid_get_pid (inferior_ptid))
        {
          /* inferior_ptid has no thread member yet.  This can happen
             with the vAttach -> remote_wait,"TAAthread:" path if the
             stub doesn't support qC.  This is the first stop reported
             after an attach, so this is the main thread.  Update the
             ptid in the thread list.  */
-         thread_change_ptid (inferior_ptid, currthread);
+         if (in_thread_list (pid_to_ptid (pid)))
+           thread_change_ptid (inferior_ptid, currthread);
+         else
+           {
+             remote_add_thread (currthread, running);
+             inferior_ptid = currthread;
+           }
          return;
        }
 
@@ -1207,7 +1264,7 @@ remote_notice_new_inferior (ptid_t currthread, int running)
         may not know about it yet.  Add it before adding its child
         thread, so notifications are emitted in a sensible order.  */
       if (!in_inferior_list (ptid_get_pid (currthread)))
-       inf = remote_add_inferior (ptid_get_pid (currthread));
+       inf = remote_add_inferior (ptid_get_pid (currthread), -1);
 
       /* This is really a new thread.  Add it.  */
       remote_add_thread (currthread, running);
@@ -2349,8 +2406,6 @@ remote_close (int quitting)
     delete_async_event_handler (&remote_async_inferior_event_token);
   if (remote_async_get_pending_events_token)
     delete_async_event_handler (&remote_async_get_pending_events_token);
-
-  generic_mourn_inferior ();
 }
 
 /* Query the remote side for the text, data and bss offsets.  */
@@ -2665,7 +2720,7 @@ remote_start_remote (struct ui_out *uiout, void *opaque)
       /* Now, if we have thread information, update inferior_ptid.  */
       inferior_ptid = remote_current_thread (inferior_ptid);
 
-      remote_add_inferior (ptid_get_pid (inferior_ptid));
+      remote_add_inferior (ptid_get_pid (inferior_ptid), -1);
 
       /* Always add the main thread.  */
       add_thread_silent (inferior_ptid);
@@ -2693,6 +2748,13 @@ remote_start_remote (struct ui_out *uiout, void *opaque)
     }
   else
     {
+      /* Clear WFI global state.  Do this before finding about new
+        threads and inferiors, and setting the current inferior.
+        Otherwise we would clear the proceed status of the current
+        inferior when we want its stop_soon state to be preserved
+        (see notice_new_inferior).  */
+      init_wait_for_inferior ();
+
       /* In non-stop, we will either get an "OK", meaning that there
         are no stopped threads at this time; or, a regular stop
         reply.  In the latter case, there may be more than one thread
@@ -2762,9 +2824,8 @@ remote_start_remote (struct ui_out *uiout, void *opaque)
        remote_check_symbols (symfile_objfile);
     }
 
-  /* If code is shared between processes, then breakpoints are global
-     too; Insert them now.  */
-  if (gdbarch_has_global_solist (target_gdbarch)
+  /* If breakpoints are global, insert them now.  */
+  if (gdbarch_has_global_breakpoints (target_gdbarch)
       && breakpoints_always_inserted_mode ())
     insert_breakpoints ();
 }
@@ -3390,7 +3451,6 @@ extended_remote_attach_1 (struct target_ops *target, char *args, int from_tty)
   int pid;
   char *dummy;
   char *wait_status = NULL;
-  struct inferior *inf;
 
   if (!args)
     error_no_arg (_("process-id to attach"));
@@ -3431,20 +3491,34 @@ extended_remote_attach_1 (struct target_ops *target, char *args, int from_tty)
     error (_("Attaching to %s failed"),
           target_pid_to_str (pid_to_ptid (pid)));
 
+  remote_add_inferior (pid, 1);
+
   inferior_ptid = pid_to_ptid (pid);
 
-  /* Now, if we have thread information, update inferior_ptid.  */
-  inferior_ptid = remote_current_thread (inferior_ptid);
+  if (non_stop)
+    {
+      struct thread_info *thread;
 
-  inf = remote_add_inferior (pid);
-  inf->attach_flag = 1;
+      /* Get list of threads.  */
+      remote_threads_info (target);
 
-  if (non_stop)
-    /* Get list of threads.  */
-    remote_threads_info (target);
+      thread = first_thread_of_process (pid);
+      if (thread)
+       inferior_ptid = thread->ptid;
+      else
+       inferior_ptid = pid_to_ptid (pid);
+
+      /* Invalidate our notion of the remote current thread.  */
+      record_currthread (minus_one_ptid);
+    }
   else
-    /* Add the main thread to the thread list.  */
-    add_thread_silent (inferior_ptid);
+    {
+      /* Now, if we have thread information, update inferior_ptid.  */
+      inferior_ptid = remote_current_thread (inferior_ptid);
+
+      /* Add the main thread to the thread list.  */
+      add_thread_silent (inferior_ptid);
+    }
 
   /* Next, if the target can specify a description, read it.  We do
      this before anything involving memory or registers.  */
@@ -3597,6 +3671,50 @@ remote_vcont_probe (struct remote_state *rs)
   packet_ok (buf, &remote_protocol_packets[PACKET_vCont]);
 }
 
+/* Helper function for building "vCont" resumptions.  Write a
+   resumption to P.  ENDP points to one-passed-the-end of the buffer
+   we're allowed to write to.  Returns BUF+CHARACTERS_WRITTEN.  The
+   thread to be resumed is PTID; STEP and SIGGNAL indicate whether the
+   resumed thread should be single-stepped and/or signalled.  If PTID
+   equals minus_one_ptid, then all threads are resumed; if PTID
+   represents a process, then all threads of the process are resumed;
+   the thread to be stepped and/or signalled is given in the global
+   INFERIOR_PTID.  */
+
+static char *
+append_resumption (char *p, char *endp,
+                  ptid_t ptid, int step, enum target_signal siggnal)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  if (step && siggnal != TARGET_SIGNAL_0)
+    p += xsnprintf (p, endp - p, ";S%02x", siggnal);
+  else if (step)
+    p += xsnprintf (p, endp - p, ";s");
+  else if (siggnal != TARGET_SIGNAL_0)
+    p += xsnprintf (p, endp - p, ";C%02x", siggnal);
+  else
+    p += xsnprintf (p, endp - p, ";c");
+
+  if (remote_multi_process_p (rs) && ptid_is_pid (ptid))
+    {
+      ptid_t nptid;
+
+      /* All (-1) threads of process.  */
+      nptid = ptid_build (ptid_get_pid (ptid), 0, -1);
+
+      p += xsnprintf (p, endp - p, ":");
+      p = write_ptid (p, endp, nptid);
+    }
+  else if (!ptid_equal (ptid, minus_one_ptid))
+    {
+      p += xsnprintf (p, endp - p, ":");
+      p = write_ptid (p, endp, ptid);
+    }
+
+  return p;
+}
+
 /* Resume the remote inferior by using a "vCont" packet.  The thread
    to be resumed is PTID; STEP and SIGGNAL indicate whether the
    resumed thread should be single-stepped and/or signalled.  If PTID
@@ -3627,78 +3745,35 @@ remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
      about overflowing BUF.  Should there be a generic
      "multi-part-packet" packet?  */
 
+  p += xsnprintf (p, endp - p, "vCont");
+
   if (ptid_equal (ptid, magic_null_ptid))
     {
       /* MAGIC_NULL_PTID means that we don't have any active threads,
         so we don't have any TID numbers the inferior will
         understand.  Make sure to only send forms that do not specify
         a TID.  */
-      if (step && siggnal != TARGET_SIGNAL_0)
-       xsnprintf (p, endp - p, "vCont;S%02x", siggnal);
-      else if (step)
-       xsnprintf (p, endp - p, "vCont;s");
-      else if (siggnal != TARGET_SIGNAL_0)
-       xsnprintf (p, endp - p, "vCont;C%02x", siggnal);
-      else
-       xsnprintf (p, endp - p, "vCont;c");
+      p = append_resumption (p, endp, minus_one_ptid, step, siggnal);
     }
-  else if (ptid_equal (ptid, minus_one_ptid))
+  else if (ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid))
     {
-      /* Resume all threads, with preference for INFERIOR_PTID.  */
-      if (step && siggnal != TARGET_SIGNAL_0)
-       {
-         /* Step inferior_ptid with signal.  */
-         p += xsnprintf (p, endp - p, "vCont;S%02x:", siggnal);
-         p = write_ptid (p, endp, inferior_ptid);
-         /* And continue others.  */
-         p += xsnprintf (p, endp - p, ";c");
-       }
-      else if (step)
-       {
-         /* Step inferior_ptid.  */
-         p += xsnprintf (p, endp - p, "vCont;s:");
-         p = write_ptid (p, endp, inferior_ptid);
-         /* And continue others.  */
-         p += xsnprintf (p, endp - p, ";c");
-       }
-      else if (siggnal != TARGET_SIGNAL_0)
+      /* Resume all threads (of all processes, or of a single
+        process), with preference for INFERIOR_PTID.  This assumes
+        inferior_ptid belongs to the set of all threads we are about
+        to resume.  */
+      if (step || siggnal != TARGET_SIGNAL_0)
        {
-         /* Continue inferior_ptid with signal.  */
-         p += xsnprintf (p, endp - p, "vCont;C%02x:", siggnal);
-         p = write_ptid (p, endp, inferior_ptid);
-         /* And continue others.  */
-         p += xsnprintf (p, endp - p, ";c");
+         /* Step inferior_ptid, with or without signal.  */
+         p = append_resumption (p, endp, inferior_ptid, step, siggnal);
        }
-      else
-       xsnprintf (p, endp - p, "vCont;c");
+
+      /* And continue others without a signal.  */
+      p = append_resumption (p, endp, ptid, /*step=*/ 0, TARGET_SIGNAL_0);
     }
   else
     {
       /* Scheduler locking; resume only PTID.  */
-      if (step && siggnal != TARGET_SIGNAL_0)
-       {
-         /* Step ptid with signal.  */
-         p += xsnprintf (p, endp - p, "vCont;S%02x:", siggnal);
-         p = write_ptid (p, endp, ptid);
-       }
-      else if (step)
-       {
-         /* Step ptid.  */
-         p += xsnprintf (p, endp - p, "vCont;s:");
-         p = write_ptid (p, endp, ptid);
-       }
-      else if (siggnal != TARGET_SIGNAL_0)
-       {
-         /* Continue ptid with signal.  */
-         p += xsnprintf (p, endp - p, "vCont;C%02x:", siggnal);
-         p = write_ptid (p, endp, ptid);
-       }
-      else
-       {
-         /* Continue ptid.  */
-         p += xsnprintf (p, endp - p, "vCont;c:");
-         p = write_ptid (p, endp, ptid);
-       }
+      p = append_resumption (p, endp, ptid, step, siggnal);
     }
 
   gdb_assert (strlen (rs->buf) < get_remote_packet_size ());
@@ -3893,13 +3968,13 @@ remote_stop_ns (ptid_t ptid)
   if (!rs->support_vCont_t)
     error (_("Remote server does not support stopping threads"));
 
-  if (ptid_equal (ptid, minus_one_ptid))
+  if (ptid_equal (ptid, minus_one_ptid)
+      || (!remote_multi_process_p (rs) && ptid_is_pid (ptid)))
     p += xsnprintf (p, endp - p, "vCont;t");
   else
     {
       ptid_t nptid;
 
-      /* Step inferior_ptid.  */
       p += xsnprintf (p, endp - p, "vCont;t:");
 
       if (ptid_is_pid (ptid))
@@ -4571,7 +4646,7 @@ process_stop_reply (struct stop_reply *stop_reply,
 /* The non-stop mode version of target_wait.  */
 
 static ptid_t
-remote_wait_ns (ptid_t ptid, struct target_waitstatus *status)
+remote_wait_ns (ptid_t ptid, struct target_waitstatus *status, int options)
 {
   struct remote_state *rs = get_remote_state ();
   struct remote_arch_state *rsa = get_remote_arch_state ();
@@ -4613,16 +4688,15 @@ remote_wait_ns (ptid_t ptid, struct target_waitstatus *status)
       if (stop_reply != NULL)
        return process_stop_reply (stop_reply, status);
 
-      /* Still no event.  If we're in asynchronous mode, then just
+      /* Still no event.  If we're just polling for an event, then
         return to the event loop.  */
-      if (remote_is_async_p ())
+      if (options & TARGET_WNOHANG)
        {
          status->kind = TARGET_WAITKIND_IGNORE;
          return minus_one_ptid;
        }
 
-      /* Otherwise, asynchronous mode is masked, so do a blocking
-        wait.  */
+      /* Otherwise do a blocking wait.  */
       ret = getpkt_or_notif_sane (&rs->buf, &rs->buf_size,
                                  1 /* forever */);
     }
@@ -4632,7 +4706,7 @@ remote_wait_ns (ptid_t ptid, struct target_waitstatus *status)
    STATUS just as `wait' would.  */
 
 static ptid_t
-remote_wait_as (ptid_t ptid, struct target_waitstatus *status)
+remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options)
 {
   struct remote_state *rs = get_remote_state ();
   struct remote_arch_state *rsa = get_remote_arch_state ();
@@ -4642,6 +4716,8 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status)
   char *buf, *p;
   struct stop_reply *stop_reply;
 
+ again:
+
   status->kind = TARGET_WAITKIND_IGNORE;
   status->value.integer = 0;
 
@@ -4744,8 +4820,14 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status)
     }
 
   if (status->kind == TARGET_WAITKIND_IGNORE)
-    /* Nothing interesting happened.  */
-    return minus_one_ptid;
+    {
+      /* Nothing interesting happened.  If we're doing a non-blocking
+        poll, we're done.  Otherwise, go back to waiting.  */
+      if (options & TARGET_WNOHANG)
+       return minus_one_ptid;
+      else
+       goto again;
+    }
   else if (status->kind != TARGET_WAITKIND_EXITED
           && status->kind != TARGET_WAITKIND_SIGNALLED)
     {
@@ -4766,24 +4848,14 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status)
 
 static ptid_t
 remote_wait (struct target_ops *ops,
-            ptid_t ptid, struct target_waitstatus *status)
+            ptid_t ptid, struct target_waitstatus *status, int options)
 {
   ptid_t event_ptid;
 
   if (non_stop)
-    event_ptid = remote_wait_ns (ptid, status);
+    event_ptid = remote_wait_ns (ptid, status, options);
   else
-    {
-      /* In synchronous mode, keep waiting until the target stops.  In
-        asynchronous mode, always return to the event loop.  */
-
-      do
-       {
-         event_ptid = remote_wait_as (ptid, status);
-       }
-      while (status->kind == TARGET_WAITKIND_IGNORE
-            && !target_can_async_p ());
-    }
+    event_ptid = remote_wait_as (ptid, status, options);
 
   if (target_can_async_p ())
     {
@@ -6481,7 +6553,7 @@ getpkt_or_notif_sane (char **buf, long *sizeof_buf, int forever)
 
 \f
 static void
-remote_kill (void)
+remote_kill (struct target_ops *ops)
 {
   /* Use catch_errors so the user can quit from gdb even when we
      aren't on speaking terms with the remote system.  */
@@ -6513,7 +6585,7 @@ remote_vkill (int pid, struct remote_state *rs)
 }
 
 static void
-extended_remote_kill (void)
+extended_remote_kill (struct target_ops *ops)
 {
   int res;
   int pid = ptid_get_pid (inferior_ptid);
@@ -6555,20 +6627,8 @@ remote_mourn_1 (struct target_ops *target)
 {
   unpush_target (target);
 
-  /* remote_close takes care of cleaning up.  */
-}
-
-static int
-select_new_thread_callback (struct thread_info *th, void* data)
-{
-  if (!is_exited (th->ptid))
-    {
-      switch_to_thread (th->ptid);
-      printf_filtered (_("[Switching to %s]\n"),
-                      target_pid_to_str (inferior_ptid));
-      return 1;
-    }
-  return 0;
+  /* remote_close takes care of doing most of the clean up.  */
+  generic_mourn_inferior ();
 }
 
 static void
@@ -6614,16 +6674,7 @@ extended_remote_mourn_1 (struct target_ops *target)
   /* Call common code to mark the inferior as not running.     */
   generic_mourn_inferior ();
 
-  if (have_inferiors ())
-    {
-      extern void nullify_last_target_wait_ptid ();
-      /* Multi-process case.  The current process has exited, but
-        there are other processes to debug.  Switch to the first
-        available.  */
-      iterate_over_threads (select_new_thread_callback, NULL);
-      nullify_last_target_wait_ptid ();
-    }
-  else
+  if (!have_inferiors ())
     {
       if (!remote_multi_process_p (rs))
        {
@@ -6761,7 +6812,7 @@ extended_remote_create_inferior_1 (char *exec_file, char *args,
   /* Now, if we have thread information, update inferior_ptid.  */
   inferior_ptid = remote_current_thread (inferior_ptid);
 
-  remote_add_inferior (ptid_get_pid (inferior_ptid));
+  remote_add_inferior (ptid_get_pid (inferior_ptid), 0);
   add_thread_silent (inferior_ptid);
 
   /* Get updated offsets, if the stub uses qOffsets.  */
@@ -9161,6 +9212,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_vKill],
                         "vKill", "kill", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_qAttached],
+                        "qAttached", "query-attached", 0);
+
   /* Keep the old ``set remote Z-packet ...'' working.  Each individual
      Z sub-packet has its own set and show commands, but users may
      have sets to this variable in their .gdbinit files (or in their
This page took 0.044019 seconds and 4 git commands to generate.