diff options
author | Pedro Alves <palves@redhat.com> | 2015-11-30 16:05:17 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2015-11-30 18:37:55 +0000 |
commit | de979965d3f5de7e4bf2354871fe85b3f77c720e (patch) | |
tree | 68510e41aebe512f3203089e9b7daa8c0dc61a69 /gdb/remote.c | |
parent | 799a2abe613be0645b84f5aaa050f2f91e6ae3f7 (diff) | |
download | gdb-de979965d3f5de7e4bf2354871fe85b3f77c720e.zip gdb-de979965d3f5de7e4bf2354871fe85b3f77c720e.tar.gz gdb-de979965d3f5de7e4bf2354871fe85b3f77c720e.tar.bz2 |
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-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.
Diffstat (limited to 'gdb/remote.c')
-rw-r--r-- | gdb/remote.c | 65 |
1 files changed, 58 insertions, 7 deletions
diff --git a/gdb/remote.c b/gdb/remote.c index 5270bd2..7256c23 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -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. */ { |