Per-inferior/Inferior-qualified thread IDs
[binutils-gdb.git] / gdb / remote.c
index 4daaf08c4b4954b02c6d179917247d1b8f169e30..4a42da8ec27477149733bfe5c3a254044960d0be 100644 (file)
@@ -1,6 +1,6 @@
 /* Remote target communications for serial-line targets in custom GDB protocol
 
-   Copyright (C) 1988-2015 Free Software Foundation, Inc.
+   Copyright (C) 1988-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -119,12 +119,12 @@ struct remote_state;
 
 static int remote_vkill (int pid, struct remote_state *rs);
 
+static void remote_kill_k (void);
+
 static void remote_mourn (struct target_ops *ops);
 
 static void extended_remote_restart (void);
 
-static void extended_remote_mourn (struct target_ops *);
-
 static void remote_send (char **buf, long *sizeof_buf_p);
 
 static int readchar (int timeout);
@@ -1392,6 +1392,7 @@ enum {
   PACKET_qSupported,
   PACKET_qTStatus,
   PACKET_QPassSignals,
+  PACKET_QCatchSyscalls,
   PACKET_QProgramSignals,
   PACKET_qCRC,
   PACKET_qSearch_memory,
@@ -1488,6 +1489,9 @@ enum {
   /* Support remote CTRL-C.  */
   PACKET_vCtrlC,
 
+  /* Support TARGET_WAITKIND_NO_RESUMED.  */
+  PACKET_no_resumed,
+
   PACKET_MAX
 };
 
@@ -1915,7 +1919,8 @@ demand_private_info (ptid_t ptid)
       info->priv = XNEW (struct private_thread_info);
       info->private_dtor = free_private_thread_info;
       info->priv->core = -1;
-      info->priv->extra = 0;
+      info->priv->extra = NULL;
+      info->priv->name = NULL;
     }
 
   return info->priv;
@@ -1983,6 +1988,93 @@ remote_pass_signals (struct target_ops *self,
     }
 }
 
+/* If 'QCatchSyscalls' is supported, tell the remote stub
+   to report syscalls to GDB.  */
+
+static int
+remote_set_syscall_catchpoint (struct target_ops *self,
+                              int pid, int needed, int any_count,
+                              int table_size, int *table)
+{
+  char *catch_packet;
+  enum packet_result result;
+  int n_sysno = 0;
+
+  if (packet_support (PACKET_QCatchSyscalls) == PACKET_DISABLE)
+    {
+      /* Not supported.  */
+      return 1;
+    }
+
+  if (needed && !any_count)
+    {
+      int i;
+
+      /* Count how many syscalls are to be caught (table[sysno] != 0).  */
+      for (i = 0; i < table_size; i++)
+       {
+         if (table[i] != 0)
+           n_sysno++;
+       }
+    }
+
+  if (remote_debug)
+    {
+      fprintf_unfiltered (gdb_stdlog,
+                         "remote_set_syscall_catchpoint "
+                         "pid %d needed %d any_count %d n_sysno %d\n",
+                         pid, needed, any_count, n_sysno);
+    }
+
+  if (needed)
+    {
+      /* Prepare a packet with the sysno list, assuming max 8+1
+        characters for a sysno.  If the resulting packet size is too
+        big, fallback on the non-selective packet.  */
+      const int maxpktsz = strlen ("QCatchSyscalls:1") + n_sysno * 9 + 1;
+
+      catch_packet = xmalloc (maxpktsz);
+      strcpy (catch_packet, "QCatchSyscalls:1");
+      if (!any_count)
+       {
+         int i;
+         char *p;
+
+         p = catch_packet;
+         p += strlen (p);
+
+         /* Add in catch_packet each syscall to be caught (table[i] != 0).  */
+         for (i = 0; i < table_size; i++)
+           {
+             if (table[i] != 0)
+               p += xsnprintf (p, catch_packet + maxpktsz - p, ";%x", i);
+           }
+       }
+      if (strlen (catch_packet) > get_remote_packet_size ())
+       {
+         /* catch_packet too big.  Fallback to less efficient
+            non selective mode, with GDB doing the filtering.  */
+         catch_packet[sizeof ("QCatchSyscalls:1") - 1] = 0;
+       }
+    }
+  else
+    catch_packet = xstrdup ("QCatchSyscalls:0");
+
+  {
+    struct cleanup *old_chain = make_cleanup (xfree, catch_packet);
+    struct remote_state *rs = get_remote_state ();
+
+    putpkt (catch_packet);
+    getpkt (&rs->buf, &rs->buf_size, 0);
+    result = packet_ok (rs->buf, &remote_protocol_packets[PACKET_QCatchSyscalls]);
+    do_cleanups (old_chain);
+    if (result == PACKET_OK)
+      return 0;
+    else
+      return -1;
+  }
+}
+
 /* If 'QProgramSignals' is supported, tell the remote stub what
    signals it should pass through to the inferior when detaching.  */
 
@@ -2094,7 +2186,7 @@ set_general_process (void)
   struct remote_state *rs = get_remote_state ();
 
   /* If the remote can't handle multiple processes, don't bother.  */
-  if (!rs->extended || !remote_multi_process_p (rs))
+  if (!remote_multi_process_p (rs))
     return;
 
   /* We only need to change the remote current thread if it's pointing
@@ -2911,6 +3003,7 @@ remote_newthread_step (threadref *ref, void *data)
 
   item.ptid = ptid_build (pid, threadref_to_int (ref), 0);
   item.core = -1;
+  item.name = NULL;
   item.extra = NULL;
 
   VEC_safe_push (thread_item_t, context->items, &item);
@@ -3076,6 +3169,7 @@ remote_get_threads_with_qthreadinfo (struct target_ops *ops,
 
                  item.ptid = read_ptid (bufp, &bufp);
                  item.core = -1;
+                 item.name = NULL;
                  item.extra = NULL;
 
                  VEC_safe_push (thread_item_t, context->items, &item);
@@ -3875,7 +3969,9 @@ process_initial_stop_replies (int from_tty)
          && thread->suspend.waitstatus_pending_p)
        selected = thread;
 
-      if (lowest_stopped == NULL || thread->num < lowest_stopped->num)
+      if (lowest_stopped == NULL
+         || thread->inf->num < lowest_stopped->inf->num
+         || thread->per_inf_num < lowest_stopped->per_inf_num)
        lowest_stopped = thread;
 
       if (non_stop)
@@ -4461,6 +4557,8 @@ static const struct protocol_feature remote_protocol_features[] = {
     PACKET_qXfer_traceframe_info },
   { "QPassSignals", PACKET_DISABLE, remote_supported_packet,
     PACKET_QPassSignals },
+  { "QCatchSyscalls", PACKET_DISABLE, remote_supported_packet,
+    PACKET_QCatchSyscalls },
   { "QProgramSignals", PACKET_DISABLE, remote_supported_packet,
     PACKET_QProgramSignals },
   { "QStartNoAckMode", PACKET_DISABLE, remote_supported_packet,
@@ -4527,6 +4625,7 @@ static const struct protocol_feature remote_protocol_features[] = {
     PACKET_Qbtrace_conf_pt_size },
   { "vContSupported", PACKET_DISABLE, remote_supported_packet, PACKET_vContSupported },
   { "QThreadEvents", PACKET_DISABLE, remote_supported_packet, PACKET_QThreadEvents },
+  { "no-resumed", PACKET_DISABLE, remote_supported_packet, PACKET_no_resumed },
 };
 
 static char *remote_support_xml;
@@ -4603,18 +4702,15 @@ remote_query_supported (void)
 
       q = remote_query_supported_append (q, "qRelocInsn+");
 
-      if (rs->extended)
-       {
-         if (packet_set_cmd_state (PACKET_fork_event_feature)
-             != AUTO_BOOLEAN_FALSE)
-           q = remote_query_supported_append (q, "fork-events+");
-         if (packet_set_cmd_state (PACKET_vfork_event_feature)
-             != AUTO_BOOLEAN_FALSE)
-           q = remote_query_supported_append (q, "vfork-events+");
-         if (packet_set_cmd_state (PACKET_exec_event_feature)
-             != AUTO_BOOLEAN_FALSE)
-           q = remote_query_supported_append (q, "exec-events+");
-       }
+      if (packet_set_cmd_state (PACKET_fork_event_feature)
+         != AUTO_BOOLEAN_FALSE)
+       q = remote_query_supported_append (q, "fork-events+");
+      if (packet_set_cmd_state (PACKET_vfork_event_feature)
+         != AUTO_BOOLEAN_FALSE)
+       q = remote_query_supported_append (q, "vfork-events+");
+      if (packet_set_cmd_state (PACKET_exec_event_feature)
+         != AUTO_BOOLEAN_FALSE)
+       q = remote_query_supported_append (q, "exec-events+");
 
       if (packet_set_cmd_state (PACKET_vContSupported) != AUTO_BOOLEAN_FALSE)
        q = remote_query_supported_append (q, "vContSupported+");
@@ -4622,6 +4718,9 @@ remote_query_supported (void)
       if (packet_set_cmd_state (PACKET_QThreadEvents) != AUTO_BOOLEAN_FALSE)
        q = remote_query_supported_append (q, "QThreadEvents+");
 
+      if (packet_set_cmd_state (PACKET_no_resumed) != AUTO_BOOLEAN_FALSE)
+       q = remote_query_supported_append (q, "no-resumed+");
+
       /* Keep this one last to work around a gdbserver <= 7.10 bug in
         the qSupported:xmlRegisters=i386 handling.  */
       if (remote_support_xml != NULL)
@@ -4966,7 +5065,8 @@ remote_detach_1 (const char *args, int from_tty)
   /* Tell the remote target to detach.  */
   remote_detach_pid (pid);
 
-  if (from_tty && !rs->extended)
+  /* Exit only if this is the only active inferior.  */
+  if (from_tty && !rs->extended && number_of_live_inferiors () == 1)
     puts_filtered (_("Ending remote debugging.\n"));
 
   /* Check to see if we are detaching a fork parent.  Note that if we
@@ -5062,10 +5162,11 @@ remote_disconnect (struct target_ops *target, const char *args, int from_tty)
   if (args)
     error (_("Argument given to \"disconnect\" when remotely debugging."));
 
-  /* Make sure we unpush even the extended remote targets; mourn
-     won't do it.  So call remote_mourn directly instead of
-     target_mourn_inferior.  */
-  remote_mourn (target);
+  /* Make sure we unpush even the extended remote targets.  Calling
+     target_mourn_inferior won't unpush, and remote_mourn won't
+     unpush if there is more than one inferior left.  */
+  unpush_target (target);
+  generic_mourn_inferior ();
 
   if (from_tty)
     puts_filtered ("Ending remote debugging.\n");
@@ -6362,6 +6463,22 @@ Packet: '%s'\n"),
 
          if (strprefix (p, p1, "thread"))
            event->ptid = read_ptid (++p1, &p);
+         else if (strprefix (p, p1, "syscall_entry"))
+           {
+             ULONGEST sysno;
+
+             event->ws.kind = TARGET_WAITKIND_SYSCALL_ENTRY;
+             p = unpack_varlen_hex (++p1, &sysno);
+             event->ws.value.syscall_number = (int) sysno;
+           }
+         else if (strprefix (p, p1, "syscall_return"))
+           {
+             ULONGEST sysno;
+
+             event->ws.kind = TARGET_WAITKIND_SYSCALL_RETURN;
+             p = unpack_varlen_hex (++p1, &sysno);
+             event->ws.value.syscall_number = (int) sysno;
+           }
          else if (strprefix (p, p1, "watch")
                   || strprefix (p, p1, "rwatch")
                   || strprefix (p, p1, "awatch"))
@@ -6539,7 +6656,7 @@ Packet: '%s'\n"),
        event->ws.value.integer = value;
        if (*p != ';')
          error (_("stop reply packet badly formatted: %s"), buf);
-       event->ptid = read_ptid (++p, &p);
+       event->ptid = read_ptid (++p, NULL);
        break;
       }
     case 'W':          /* Target exited.  */
@@ -6596,6 +6713,10 @@ Packet: '%s'\n"),
        event->ptid = pid_to_ptid (pid);
       }
       break;
+    case 'N':
+      event->ws.kind = TARGET_WAITKIND_NO_RESUMED;
+      event->ptid = minus_one_ptid;
+      break;
     }
 
   if (target_is_non_stop_p () && ptid_equal (event->ptid, null_ptid))
@@ -6697,7 +6818,8 @@ process_stop_reply (struct stop_reply *stop_reply,
     ptid = inferior_ptid;
 
   if (status->kind != TARGET_WAITKIND_EXITED
-      && status->kind != TARGET_WAITKIND_SIGNALLED)
+      && status->kind != TARGET_WAITKIND_SIGNALLED
+      && status->kind != TARGET_WAITKIND_NO_RESUMED)
     {
       struct remote_state *rs = get_remote_state ();
       struct private_thread_info *remote_thr;
@@ -6875,7 +6997,7 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options)
       remote_fileio_request (buf, rs->ctrlc_pending_p);
       rs->ctrlc_pending_p = 0;
       break;
-    case 'T': case 'S': case 'X': case 'W':
+    case 'N': case 'T': case 'S': case 'X': case 'W':
       {
        struct stop_reply *stop_reply;
 
@@ -6914,7 +7036,9 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options)
       break;
     }
 
-  if (status->kind == TARGET_WAITKIND_IGNORE)
+  if (status->kind == TARGET_WAITKIND_NO_RESUMED)
+    return minus_one_ptid;
+  else if (status->kind == TARGET_WAITKIND_IGNORE)
     {
       /* Nothing interesting happened.  If we're doing a non-blocking
         poll, we're done.  Otherwise, go back to waiting.  */
@@ -8784,42 +8908,53 @@ kill_new_fork_children (int pid, struct remote_state *rs)
 }
 
 \f
+/* Target hook to kill the current inferior.  */
+
 static void
 remote_kill (struct target_ops *ops)
 {
+  int res = -1;
+  int pid = ptid_get_pid (inferior_ptid);
+  struct remote_state *rs = get_remote_state ();
 
-  /* Catch errors so the user can quit from gdb even when we
-     aren't on speaking terms with the remote system.  */
-  TRY
-    {
-      putpkt ("k");
-    }
-  CATCH (ex, RETURN_MASK_ERROR)
+  if (packet_support (PACKET_vKill) != PACKET_DISABLE)
     {
-      if (ex.error == TARGET_CLOSE_ERROR)
+      /* 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.  */
+      kill_new_fork_children (pid, rs);
+
+      res = remote_vkill (pid, rs);
+      if (res == 0)
        {
-         /* If we got an (EOF) error that caused the target
-            to go away, then we're done, that's what we wanted.
-            "k" is susceptible to cause a premature EOF, given
-            that the remote server isn't actually required to
-            reply to "k", and it can happen that it doesn't
-            even get to reply ACK to the "k".  */
+         target_mourn_inferior ();
          return;
        }
+    }
 
-       /* Otherwise, something went wrong.  We didn't actually kill
-          the target.  Just propagate the exception, and let the
-          user or higher layers decide what to do.  */
-       throw_exception (ex);
+  /* If we are in 'target remote' mode and we are killing the only
+     inferior, then we will tell gdbserver to exit and unpush the
+     target.  */
+  if (res == -1 && !remote_multi_process_p (rs)
+      && number_of_live_inferiors () == 1)
+    {
+      remote_kill_k ();
+
+      /* We've killed the remote end, we get to mourn it.  If we are
+        not in extended mode, mourning the inferior also unpushes
+        remote_ops from the target stack, which closes the remote
+        connection.  */
+      target_mourn_inferior ();
+
+      return;
     }
-  END_CATCH
 
-  /* We've killed the remote end, we get to mourn it.  Since this is
-     target remote, single-process, mourning the inferior also
-     unpushes remote_ops.  */
-  target_mourn_inferior ();
+  error (_("Can't kill process"));
 }
 
+/* Send a kill request to the target using the 'vKill' packet.  */
+
 static int
 remote_vkill (int pid, struct remote_state *rs)
 {
@@ -8845,55 +8980,52 @@ remote_vkill (int pid, struct remote_state *rs)
     }
 }
 
+/* Send a kill request to the target using the 'k' packet.  */
+
 static void
-extended_remote_kill (struct target_ops *ops)
+remote_kill_k (void)
 {
-  int res;
-  int pid = ptid_get_pid (inferior_ptid);
-  struct remote_state *rs = get_remote_state ();
-
-  /* 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.  */
-  kill_new_fork_children (pid, rs);
-
-  res = remote_vkill (pid, rs);
-  if (res == -1 && !(rs->extended && remote_multi_process_p (rs)))
+  /* Catch errors so the user can quit from gdb even when we
+     aren't on speaking terms with the remote system.  */
+  TRY
     {
-      /* Don't try 'k' on a multi-process aware stub -- it has no way
-        to specify the pid.  */
-
       putpkt ("k");
-#if 0
-      getpkt (&rs->buf, &rs->buf_size, 0);
-      if (rs->buf[0] != 'O' || rs->buf[0] != 'K')
-       res = 1;
-#else
-      /* Don't wait for it to die.  I'm not really sure it matters whether
-        we do or not.  For the existing stubs, kill is a noop.  */
-      res = 0;
-#endif
     }
+  CATCH (ex, RETURN_MASK_ERROR)
+    {
+      if (ex.error == TARGET_CLOSE_ERROR)
+       {
+         /* If we got an (EOF) error that caused the target
+            to go away, then we're done, that's what we wanted.
+            "k" is susceptible to cause a premature EOF, given
+            that the remote server isn't actually required to
+            reply to "k", and it can happen that it doesn't
+            even get to reply ACK to the "k".  */
+         return;
+       }
 
-  if (res != 0)
-    error (_("Can't kill process"));
-
-  target_mourn_inferior ();
+      /* Otherwise, something went wrong.  We didn't actually kill
+        the target.  Just propagate the exception, and let the
+        user or higher layers decide what to do.  */
+      throw_exception (ex);
+    }
+  END_CATCH
 }
 
 static void
 remote_mourn (struct target_ops *target)
 {
-  unpush_target (target);
+  struct remote_state *rs = get_remote_state ();
 
-  /* remote_close takes care of doing most of the clean up.  */
-  generic_mourn_inferior ();
-}
+  /* In 'target remote' mode with one inferior, we close the connection.  */
+  if (!rs->extended && number_of_live_inferiors () <= 1)
+    {
+      unpush_target (target);
 
-static void
-extended_remote_mourn (struct target_ops *target)
-{
-  struct remote_state *rs = get_remote_state ();
+      /* remote_close takes care of doing most of the clean up.  */
+      generic_mourn_inferior ();
+      return;
+    }
 
   /* In case we got here due to an error, but we're going to stay
      connected.  */
@@ -8924,10 +9056,7 @@ extended_remote_mourn (struct target_ops *target)
      current thread.  */
   record_currthread (rs, minus_one_ptid);
 
-  /* Unlike "target remote", we do not want to unpush the target; then
-     the next time the user says "run", we won't be connected.  */
-
-  /* Call common code to mark the inferior as not running.     */
+  /* Call common code to mark the inferior as not running.  */
   generic_mourn_inferior ();
 
   if (!have_inferiors ())
@@ -10449,7 +10578,7 @@ remote_pid_to_str (struct target_ops *ops, ptid_t ptid)
     {
       if (ptid_equal (magic_null_ptid, ptid))
        xsnprintf (buf, sizeof buf, "Thread <main>");
-      else if (rs->extended && remote_multi_process_p (rs))
+      else if (remote_multi_process_p (rs))
        if (ptid_get_lwp (ptid) == 0)
          return normal_pid_to_str (ptid);
        else
@@ -11619,11 +11748,7 @@ remote_supports_multi_process (struct target_ops *self)
 {
   struct remote_state *rs = get_remote_state ();
 
-  /* Only extended-remote handles being attached to multiple
-     processes, even though plain remote can use the multi-process
-     thread id extensions, so that GDB knows the target process's
-     PID.  */
-  return rs->extended && remote_multi_process_p (rs);
+  return remote_multi_process_p (rs);
 }
 
 static int
@@ -12959,6 +13084,7 @@ Specify the serial device it is connected to\n\
   remote_ops.to_load = remote_load;
   remote_ops.to_mourn_inferior = remote_mourn;
   remote_ops.to_pass_signals = remote_pass_signals;
+  remote_ops.to_set_syscall_catchpoint = remote_set_syscall_catchpoint;
   remote_ops.to_program_signals = remote_program_signals;
   remote_ops.to_thread_alive = remote_thread_alive;
   remote_ops.to_thread_name = remote_thread_name;
@@ -13055,6 +13181,14 @@ Specify the serial device it is connected to\n\
   remote_ops.to_btrace_conf = remote_btrace_conf;
   remote_ops.to_augmented_libraries_svr4_read =
     remote_augmented_libraries_svr4_read;
+  remote_ops.to_follow_fork = remote_follow_fork;
+  remote_ops.to_follow_exec = remote_follow_exec;
+  remote_ops.to_insert_fork_catchpoint = remote_insert_fork_catchpoint;
+  remote_ops.to_remove_fork_catchpoint = remote_remove_fork_catchpoint;
+  remote_ops.to_insert_vfork_catchpoint = remote_insert_vfork_catchpoint;
+  remote_ops.to_remove_vfork_catchpoint = remote_remove_vfork_catchpoint;
+  remote_ops.to_insert_exec_catchpoint = remote_insert_exec_catchpoint;
+  remote_ops.to_remove_exec_catchpoint = remote_remove_exec_catchpoint;
 }
 
 /* Set up the extended remote vector by making a copy of the standard
@@ -13073,27 +13207,11 @@ init_extended_remote_ops (void)
 Specify the serial device it is connected to (e.g. /dev/ttya).";
   extended_remote_ops.to_open = extended_remote_open;
   extended_remote_ops.to_create_inferior = extended_remote_create_inferior;
-  extended_remote_ops.to_mourn_inferior = extended_remote_mourn;
   extended_remote_ops.to_detach = extended_remote_detach;
   extended_remote_ops.to_attach = extended_remote_attach;
   extended_remote_ops.to_post_attach = extended_remote_post_attach;
-  extended_remote_ops.to_kill = extended_remote_kill;
   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_follow_exec = remote_follow_exec;
-  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;
-  extended_remote_ops.to_insert_exec_catchpoint
-    = remote_insert_exec_catchpoint;
-  extended_remote_ops.to_remove_exec_catchpoint
-    = remote_remove_exec_catchpoint;
 }
 
 static int
@@ -13533,6 +13651,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_QPassSignals],
                         "QPassSignals", "pass-signals", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_QCatchSyscalls],
+                        "QCatchSyscalls", "catch-syscalls", 0);
+
   add_packet_config_cmd (&remote_protocol_packets[PACKET_QProgramSignals],
                         "QProgramSignals", "program-signals", 0);
 
@@ -13755,6 +13876,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_QThreadEvents],
                         "QThreadEvents", "thread-events", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_no_resumed],
+                        "N stop reply", "no-resumed-stop-reply", 0);
+
   /* Assert that we've registered "set remote foo-packet" commands
      for all packet configs.  */
   {