New vCtrlC packet, non-stop mode equivalent of \003
authorPedro Alves <palves@redhat.com>
Mon, 30 Nov 2015 16:05:17 +0000 (16:05 +0000)
committerPedro Alves <palves@redhat.com>
Mon, 30 Nov 2015 18:37:55 +0000 (18:37 +0000)
There's currently no non-stop equivalent of the all-stop ^C (\003)
"packet" that GDB sends when a ctrl-c is pressed while a foreground
command is active.  There's vCont;t, but that's defined to cause a
"signal 0" stop.

This fixes many tests that type ^C, when testing with extended-remote
with "maint set target-non-stop on".  E.g.:

 Continuing.
 talk to me baby
 PASS: gdb.base/interrupt.exp: process is alive
 a
 a
 PASS: gdb.base/interrupt.exp: child process ate our char
 ^C
 [Thread 22730.22730] #1 stopped.
 0x0000003615ee6650 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:81
 81      T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
 (gdb) FAIL: gdb.base/interrupt.exp: send_gdb control C
 p func1 ()

gdb/
2015-11-30  Pedro Alves  <palves@redhat.com>

* NEWS (New remote packets): Mention vCtrlC.
* remote.c (PACKET_vCtrlC): New enum value.
(async_remote_interrupt): Call target_interrupt instead of
target_stop.
(remote_interrupt_as): Remove 'ptid' parameter.
(remote_interrupt_ns): New function.
(remote_stop): Adjust.
(remote_interrupt): If the target is in non-stop mode, try
interrupting with vCtrlC.
(initialize_remote): Install set remote ctrl-c packet.

gdb/doc/
2015-11-30  Pedro Alves  <palves@redhat.com>

* gdb.texinfo (Bootstrapping): Add "interrupting remote targets"
anchor.
(Packets): Document vCtrlC.

gdb/gdbserver/
2015-11-30  Pedro Alves  <palves@redhat.com>

* server.c (handle_v_requests): Handle vCtrlC.

gdb/ChangeLog
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/gdbserver/ChangeLog
gdb/gdbserver/server.c
gdb/remote.c

index a0eff91..0d4ea33 100644 (file)
@@ -1,5 +1,18 @@
 2015-11-30  Pedro Alves  <palves@redhat.com>
 
+       * NEWS (New remote packets): Mention vCtrlC.
+       * remote.c (PACKET_vCtrlC): New enum value.
+       (async_remote_interrupt): Call target_interrupt instead of
+       target_stop.
+       (remote_interrupt_as): Remove 'ptid' parameter.
+       (remote_interrupt_ns): New function.
+       (remote_stop): Adjust.
+       (remote_interrupt): If the target is in non-stop mode, try
+       interrupting with vCtrlC.
+       (initialize_remote): Install set remote ctrl-c packet.
+
+2015-11-30  Pedro Alves  <palves@redhat.com>
+
        * remote.c (struct remote_state) <remote_watch_data_address,
        stop_reason>: Delete fields.
        (struct private_thread_info) <stop_reason, watch_data_address>:
index 5f704fe..a7c12e7 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -84,6 +84,10 @@ exec-events feature in qSupported
   response can contain the corresponding 'stubfeature'.  Set and
   show commands can be used to display whether these features are enabled.
 
+vCtrlC
+  Equivalent to interrupting with the ^C character, but works in
+  non-stop mode.
+
 * Extended-remote exec events
 
   ** GDB now has support for exec events on extended-remote Linux targets.
index 7e747dc..3e0d626 100644 (file)
@@ -1,3 +1,9 @@
+2015-11-30  Pedro Alves  <palves@redhat.com>
+
+       * gdb.texinfo (Bootstrapping): Add "interrupting remote targets"
+       anchor.
+       (Packets): Document vCtrlC.
+
 2015-11-26  Simon Marchi  <simon.marchi@ericsson.com>
 
        * gdb.texinfo (Thread List Format): Mention thread names.
index c4d8a18..972ace0 100644 (file)
@@ -35090,6 +35090,24 @@ command in the @samp{vCont} packet.
 The @samp{vCont} packet is not supported.
 @end table
 
+@anchor{vCtrlC packet}
+@item vCtrlC
+@cindex @samp{vCtrlC} packet
+Interrupt remote target as if a control-C was pressed on the remote
+terminal.  This is the equivalent to reacting to the @code{^C}
+(@samp{\003}, the control-C character) character in all-stop mode
+while the target is running, except this works in non-stop mode.
+@xref{interrupting remote targets}, for more info on the all-stop
+variant.
+
+Reply:
+@table @samp
+@item E @var{nn}
+for an error
+@item OK
+for success
+@end table
+
 @item vFile:@var{operation}:@var{parameter}@dots{}
 @cindex @samp{vFile} packet
 Perform a file operation on the target system.  For details,
@@ -37857,11 +37875,12 @@ operation.
 @node Interrupts
 @section Interrupts
 @cindex interrupts (remote protocol)
+@anchor{interrupting remote targets}
 
-When a program on the remote target is running, @value{GDBN} may
-attempt to interrupt it by sending a @samp{Ctrl-C}, @code{BREAK} or
-a @code{BREAK} followed by @code{g},
-control of which is specified via @value{GDBN}'s @samp{interrupt-sequence}.
+In all-stop mode, when a program on the remote target is running,
+@value{GDBN} may attempt to interrupt it by sending a @samp{Ctrl-C},
+@code{BREAK} or a @code{BREAK} followed by @code{g}, control of which
+is specified via @value{GDBN}'s @samp{interrupt-sequence}.
 
 The precise meaning of @code{BREAK} is defined by the transport
 mechanism and may, in fact, be undefined.  @value{GDBN} does not
@@ -37882,6 +37901,13 @@ and does @emph{not} represent an interrupt.  E.g., an @samp{X} packet
 When Linux kernel receives this sequence from serial port,
 it stops execution and connects to gdb.
 
+In non-stop mode, because packet resumptions are asynchronous
+(@pxref{vCont packet}), @value{GDBN} is always free to send a remote
+command to the remote stub, even when the target is running.  For that
+reason, @value{GDBN} instead sends a regular packet (@pxref{vCtrlC
+packet}) with the usual packet framing instead of the single byte
+@code{0x03}.
+
 Stubs are not required to recognize these interrupt mechanisms and the
 precise meaning associated with receipt of the interrupt is
 implementation defined.  If the target supports debugging of multiple
index 28ff0e1..22d729f 100644 (file)
@@ -1,5 +1,9 @@
 2015-11-30  Pedro Alves  <palves@redhat.com>
 
+       * server.c (handle_v_requests): Handle vCtrlC.
+
+2015-11-30  Pedro Alves  <palves@redhat.com>
+
        * gdbthread.h (find_any_thread_of_pid): Declare.
        * inferiors.c (thread_of_pid, find_any_thread_of_pid): New
        functions.
index 9d65f65..f6245d7 100644 (file)
@@ -2861,6 +2861,13 @@ handle_v_requests (char *own_buf, int packet_len, int *new_packet_len)
 {
   if (!disable_packet_vCont)
     {
+      if (strcmp (own_buf, "vCtrlC") == 0)
+       {
+         (*the_target->request_interrupt) ();
+         write_ok (own_buf);
+         return;
+       }
+
       if (startswith (own_buf, "vCont;"))
        {
          require_running (own_buf);
index 5270bd2..7256c23 100644 (file)
@@ -1480,6 +1480,9 @@ enum {
   /* Support for query supported vCont actions.  */
   PACKET_vContSupported,
 
+  /* Support remote CTRL-C.  */
+  PACKET_vCtrlC,
+
   PACKET_MAX
 };
 
@@ -5581,7 +5584,7 @@ async_remote_interrupt (gdb_client_data arg)
   if (remote_debug)
     fprintf_unfiltered (gdb_stdlog, "async_remote_interrupt called\n");
 
-  target_stop (inferior_ptid);
+  target_interrupt (inferior_ptid);
 }
 
 /* Perform interrupt, if the first attempt did not succeed.  Just give
@@ -5688,7 +5691,7 @@ remote_stop_ns (ptid_t ptid)
    process reports the interrupt.  */
 
 static void
-remote_interrupt_as (ptid_t ptid)
+remote_interrupt_as (void)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -5704,6 +5707,38 @@ remote_interrupt_as (ptid_t ptid)
   send_interrupt_sequence ();
 }
 
+/* Non-stop version of target_interrupt.  Uses `vCtrlC' to interrupt
+   the remote target.  It is undefined which thread of which process
+   reports the interrupt.  Returns true if the packet is supported by
+   the server, false otherwise.  */
+
+static int
+remote_interrupt_ns (void)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *p = rs->buf;
+  char *endp = rs->buf + get_remote_packet_size ();
+
+  xsnprintf (p, endp - p, "vCtrlC");
+
+  /* In non-stop, we get an immediate OK reply.  The stop reply will
+     come in asynchronously by notification.  */
+  putpkt (rs->buf);
+  getpkt (&rs->buf, &rs->buf_size, 0);
+
+  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_vCtrlC]))
+    {
+    case PACKET_OK:
+      break;
+    case PACKET_UNKNOWN:
+      return 0;
+    case PACKET_ERROR:
+      error (_("Interrupting target failed: %s"), rs->buf);
+    }
+
+  return 1;
+}
+
 /* Implement the to_stop function for the remote targets.  */
 
 static void
@@ -5718,7 +5753,7 @@ remote_stop (struct target_ops *self, ptid_t ptid)
     {
       /* We don't currently have a way to transparently pause the
         remote target in all-stop mode.  Interrupt it instead.  */
-      remote_interrupt_as (ptid);
+      remote_interrupt_as ();
     }
 }
 
@@ -5730,14 +5765,27 @@ remote_interrupt (struct target_ops *self, ptid_t ptid)
   if (remote_debug)
     fprintf_unfiltered (gdb_stdlog, "remote_interrupt called\n");
 
-  if (target_is_non_stop_p ())
+  if (non_stop)
     {
-      /* We don't currently have a way to ^C the remote target in
-        non-stop mode.  Stop it (with no signal) instead.  */
+      /* In non-stop mode, we always stop with no signal instead.  */
       remote_stop_ns (ptid);
     }
   else
-    remote_interrupt_as (ptid);
+    {
+      /* In all-stop, we emulate ^C-ing the remote target's
+        terminal.  */
+      if (target_is_non_stop_p ())
+       {
+         if (!remote_interrupt_ns ())
+           {
+             /* No support for ^C-ing the remote target.  Stop it
+                (with no signal) instead.  */
+             remote_stop_ns (ptid);
+           }
+       }
+      else
+       remote_interrupt_as ();
+    }
 }
 
 /* Ask the user what to do when an interrupt is received.  */
@@ -13643,6 +13691,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_exec_event_feature],
                         "exec-event-feature", "exec-event-feature", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_vCtrlC],
+                        "vCtrlC", "ctrl-c", 0);
+
   /* Assert that we've registered "set remote foo-packet" commands
      for all packet configs.  */
   {