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

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