summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2015-10-10 12:25:44 +0100
committerPedro Alves <palves@redhat.com>2015-10-14 16:04:32 +0100
commita68db5da032742d4da8c9fe30376cce54b2135b2 (patch)
tree86fc74483ae9f38f11d6b9b77fff70d79128fb37
parent2733f5a2f0cb456c079a873bd89c8b945acdd7ce (diff)
downloadbinutils-gdb-a68db5da032742d4da8c9fe30376cce54b2135b2.tar.gz
New vCtrlC packet, non-stop mode equivalent of \003
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-10-14 Pedro Alves <palves@redhat.com> * NEWS (New remote packets): Mention vCtrlC. gdb/doc/ 2015-10-14 Pedro Alves <palves@redhat.com> * gdb.texinfo (Bootstrapping): Add "interrupting remote targets" anchor. (Packets): Document vCtrlC. gdb/gdbserver/ 2015-10-14 Pedro Alves <palves@redhat.com> * server.c (handle_v_requests): Handle 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.
-rw-r--r--gdb/NEWS4
-rw-r--r--gdb/doc/gdb.texinfo34
-rw-r--r--gdb/gdbserver/server.c7
-rw-r--r--gdb/remote.c64
4 files changed, 98 insertions, 11 deletions
diff --git a/gdb/NEWS b/gdb/NEWS
index 2e38d9a6c8d..84c75cc7723 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -75,6 +75,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.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index f298172da27..196a842dbac 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -35087,6 +35087,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,
@@ -37854,11 +37872,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
@@ -37879,6 +37898,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
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index ec52f841c8c..e0ce524ec5c 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -2849,6 +2849,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);
diff --git a/gdb/remote.c b/gdb/remote.c
index 10c65e2fcce..9a23ca6e6c0 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -1478,6 +1478,9 @@ enum {
/* Support for query supported vCont actions. */
PACKET_vContSupported,
+ /* Support remote CTRL-C. */
+ PACKET_vCtrlC,
+
PACKET_MAX
};
@@ -5553,7 +5556,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
@@ -5660,7 +5663,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 ();
@@ -5676,6 +5679,37 @@ 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. */
+
+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
@@ -5690,7 +5724,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 ();
}
}
@@ -5702,14 +5736,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. */
@@ -13612,6 +13659,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. */
{