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 a0eff91237b56a218a38ba7fc23bdfbd5e0b828d..0d4ea33a44efa0201e7dd54e38227ed21a8cb1d0 100644 (file)
@@ -1,3 +1,16 @@
+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,
index 5f704fe472cb709603f276fbe2ee74b735f74361..a7c12e79f34c04bc8e0836385939d99db2acabc7 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 7e747dcf8b4bf72cac12a6f46a98f9e3ea50c282..3e0d6262f242fe828dd3147b3a9d75ebf4baf313 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 c4d8a186774d96d14222f2aeb024ed1886ff21ad..972ace08d994ac1ce1f0c68d03822a3a5924ca8a 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 28ff0e1ac9603df8ef93052fc427930358b8b798..22d729f0db809715fb3d64f2438144f7c580f022 100644 (file)
@@ -1,3 +1,7 @@
+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.
index 9d65f6520d9f7582d5225b6d06700fa5efe5d961..f6245d76f75a8139e6cf421340fa9856add5952f 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 5270bd281d370e16ae85434942f2aba712b1c7c8..7256c23b4ffb697551a0362e134c28feecb96668 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.  */
   {