This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[commit/remote] Handle Control-C more thoroughly during file I/O
- From: Daniel Jacobowitz <drow at false dot org>
- To: gdb-patches at sourceware dot org
- Cc: Kazu Hirata <kazu at codesourcery dot com>, Maxim Kuvyrkov <maxim at codesourcery dot com>
- Date: Fri, 13 Nov 2009 17:41:04 -0500
- Subject: [commit/remote] Handle Control-C more thoroughly during file I/O
We discovered during test runs of a somewhat broken toolchain that
sending an interrupt sometimes didn't stop programs on one of our
target systems. Kazu eventually tracked down the problem: the target
was stuck in a loop sending semi-hosting (remote file I/O) requests.
Remote stubs vary in how well they handle the all-stop interrupt
request, which is a single out-of-band \003 (control-c). In many
cases, it works only when the target is running. If GDB thinks the
target is running, but the target has already send a file I/O stop
reply, the target may discard the \003 - the program is already
stopped when it's received!
This patch changes GDB to keep track of such likely-discarded events.
The file I/O protocol has an explicit message to say that an operation
completed by being interrupted, so we use it here, even though the
interrupt appeared to happen before the file I/O request was initiated
(from GDB's perspective, but not from the target's).
Tested on arm-none-eabi. Checked in.
2009-11-13 Kazu Hirata <kazu@codesourcery.com>
Maxim Kuvyrkov <maxim@codesourcery.com>
* remote-fileio.c (remote_fileio_request): Send Ctrl-C if it is
pending.
* remote-fileio.h: Update the prototype for remote_fileio_request.
* remote.c (struct remote_state): Add ctrlc_pending_p.
(remote_open_1): Clear ctrlc_pending_p.
(remote_stop_as): Set ctrlc_pending_p to 1.
(remote_wait_as): Pass ctrlc_pending_p to remote_fileio_request.
---
gdb/remote-fileio.c | 46 +++++++++++++++++++++++++++++++---------------
gdb/remote-fileio.h | 2 +-
gdb/remote.c | 15 ++++++++++++++-
3 files changed, 46 insertions(+), 17 deletions(-)
Index: gdb/remote-fileio.c
===================================================================
--- gdb/remote-fileio.c.orig 2009-11-12 13:36:35.000000000 -0800
+++ gdb/remote-fileio.c 2009-11-13 09:06:05.000000000 -0800
@@ -1416,28 +1416,44 @@ remote_fileio_reset (void)
}
}
+/* Handle a file I/O request. BUF points to the packet containing the
+ request. CTRLC_PENDING_P should be nonzero if the target has not
+ acknowledged the Ctrl-C sent asynchronously earlier. */
+
void
-remote_fileio_request (char *buf)
+remote_fileio_request (char *buf, int ctrlc_pending_p)
{
int ex;
remote_fileio_sig_init ();
- remote_fio_ctrl_c_flag = 0;
- remote_fio_no_longjmp = 0;
-
- ex = catch_exceptions (uiout, do_remote_fileio_request, (void *)buf,
- RETURN_MASK_ALL);
- switch (ex)
+ if (ctrlc_pending_p)
+ {
+ /* If the target hasn't responded to the Ctrl-C sent
+ asynchronously earlier, take this opportunity to send the
+ Ctrl-C synchronously. */
+ remote_fio_ctrl_c_flag = 1;
+ remote_fio_no_longjmp = 0;
+ remote_fileio_reply (-1, FILEIO_EINTR);
+ }
+ else
{
- case RETURN_ERROR:
- remote_fileio_reply (-1, FILEIO_ENOSYS);
- break;
- case RETURN_QUIT:
- remote_fileio_reply (-1, FILEIO_EINTR);
- break;
- default:
- break;
+ remote_fio_ctrl_c_flag = 0;
+ remote_fio_no_longjmp = 0;
+
+ ex = catch_exceptions (uiout, do_remote_fileio_request, (void *)buf,
+ RETURN_MASK_ALL);
+ switch (ex)
+ {
+ case RETURN_ERROR:
+ remote_fileio_reply (-1, FILEIO_ENOSYS);
+ break;
+ case RETURN_QUIT:
+ remote_fileio_reply (-1, FILEIO_EINTR);
+ break;
+ default:
+ break;
+ }
}
remote_fileio_sig_exit ();
Index: gdb/remote-fileio.h
===================================================================
--- gdb/remote-fileio.h.orig 2009-01-03 00:43:30.000000000 -0800
+++ gdb/remote-fileio.h 2009-11-13 09:06:05.000000000 -0800
@@ -26,7 +26,7 @@ struct cmd_list_element;
/* Unified interface to remote fileio, called in remote.c from
remote_wait () and remote_async_wait () */
-extern void remote_fileio_request (char *buf);
+extern void remote_fileio_request (char *buf, int ctrlc_pending_p);
/* Cleanup any remote fileio state. */
extern void remote_fileio_reset (void);
Index: gdb/remote.c
===================================================================
--- gdb/remote.c.orig 2009-10-29 00:44:54.000000000 -0700
+++ gdb/remote.c 2009-11-13 09:20:51.000000000 -0800
@@ -297,6 +297,10 @@ struct remote_state
/* True if the stub reports support for conditional tracepoints. */
int cond_tracepoints;
+
+ /* Nonzero if the user has pressed Ctrl-C, but the target hasn't
+ responded to that. */
+ int ctrlc_pending_p;
};
/* Returns true if the multi-process extensions are in effect. */
@@ -3394,6 +3398,7 @@ remote_open_1 (char *name, int from_tty,
rs->extended = extended_p;
rs->non_stop_aware = 0;
rs->waiting_for_stop_reply = 0;
+ rs->ctrlc_pending_p = 0;
general_thread = not_sent_ptid;
continue_thread = not_sent_ptid;
@@ -4122,6 +4127,8 @@ remote_stop_as (ptid_t ptid)
{
struct remote_state *rs = get_remote_state ();
+ rs->ctrlc_pending_p = 1;
+
/* If the inferior is stopped already, but the core didn't know
about it yet, just ignore the request. The cached wait status
will be collected in remote_wait. */
@@ -4848,6 +4855,11 @@ remote_wait_as (ptid_t ptid, struct targ
/* We got something. */
rs->waiting_for_stop_reply = 0;
+ /* Assume that the target has acknowledged Ctrl-C unless we receive
+ an 'F' or 'O' packet. */
+ if (buf[0] != 'F' && buf[0] != 'O')
+ rs->ctrlc_pending_p = 0;
+
switch (buf[0])
{
case 'E': /* Error of some sort. */
@@ -4858,7 +4870,8 @@ remote_wait_as (ptid_t ptid, struct targ
status->value.sig = TARGET_SIGNAL_0;
break;
case 'F': /* File-I/O request. */
- remote_fileio_request (buf);
+ remote_fileio_request (buf, rs->ctrlc_pending_p);
+ rs->ctrlc_pending_p = 0;
break;
case 'T': case 'S': case 'X': case 'W':
{
--
Daniel Jacobowitz
CodeSourcery