From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1362 invoked by alias); 14 Oct 2015 15:36:38 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 1346 invoked by uid 89); 14 Oct 2015 15:36:37 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Wed, 14 Oct 2015 15:36:36 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 7226A8E704 for ; Wed, 14 Oct 2015 15:28:14 +0000 (UTC) Received: from brno.lan (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9EFS6Df016846 for ; Wed, 14 Oct 2015 11:28:13 -0400 From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH 06/18] New vCtrlC packet, non-stop mode equivalent of \003 Date: Wed, 14 Oct 2015 15:36:00 -0000 Message-Id: <1444836486-25679-7-git-send-email-palves@redhat.com> In-Reply-To: <1444836486-25679-1-git-send-email-palves@redhat.com> References: <1444836486-25679-1-git-send-email-palves@redhat.com> X-SW-Source: 2015-10/txt/msg00223.txt.bz2 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 * NEWS (New remote packets): Mention vCtrlC. gdb/doc/ 2015-10-14 Pedro Alves * gdb.texinfo (Bootstrapping): Add "interrupting remote targets" anchor. (Packets): Document vCtrlC. gdb/gdbserver/ 2015-10-14 Pedro Alves * 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. --- gdb/NEWS | 4 ++++ gdb/doc/gdb.texinfo | 34 +++++++++++++++++++++++---- gdb/gdbserver/server.c | 7 ++++++ gdb/remote.c | 64 ++++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 98 insertions(+), 11 deletions(-) diff --git a/gdb/NEWS b/gdb/NEWS index 2e38d9a..84c75cc 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 f298172..196a842 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 ec52f84..e0ce524 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 10c65e2..9a23ca6 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. */ { -- 1.9.3