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.
This commit is contained in:
Pedro Alves 2015-11-30 16:05:17 +00:00
parent 799a2abe61
commit de979965d3
7 changed files with 122 additions and 11 deletions

View 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,

View File

@ -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.

View 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.

View 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

View 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.

View 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);

View 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. */
{