From 29090fb629734b7980f058f4a7e24a0369e9bb49 Mon Sep 17 00:00:00 2001 From: Luis Machado Date: Mon, 19 Oct 2015 11:33:19 -0200 Subject: [PATCH] Make GDB wait for events after handling target File-I/O _ftext () at arm-vector.S:25 25 ldr pc, [pc, #24] @ reset (gdb) load Loading section .text, size 0xc01c lma 0x0 Loading section .eh_frame, size 0x48 lma 0xc01c Loading section .ARM.exidx, size 0x8 lma 0xc064 Loading section .rodata, size 0x398 lma 0xc070 Loading section .data, size 0x8e0 lma 0xc408 Start address 0x40, load size 52452 Transfer rate: 17074 KB/sec, 1748 bytes/write. (gdb) c Continuing. infrun: clear_proceed_status_thread (Thread 1) infrun: proceed (addr=0xffffffff, signal=GDB_SIGNAL_DEFAULT) infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 1] at 0x40 Sending packet: $vCont?#49...Ack Packet received: Packet vCont (verbose-resume) is NOT supported Sending packet: $Hc0#db...Ack Packet received: OK Sending packet: $c#63...Ack infrun: infrun_async(1) infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun: -1.0.0 [Thread 0], infrun: status->kind = ignore infrun: TARGET_WAITKIND_IGNORE infrun: prepare_to_wait Packet received: Ffstat,00000001,07fffdb0 Sending packet: $M7fffdb0,40:000000000000000000002080000000010000c336000001180000000000000000000000000000000000000200000000000000000055dfb11b55dfb11b55dfb11b#5a...Ack Packet received: OK Sending packet: $F0#76...Ack infrun: target_wait (-1.0.0, status) = infrun: -1.0.0 [Thread 0], infrun: status->kind = ignore infrun: TARGET_WAITKIND_IGNORE infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun: -1.0.0 [Thread 0], infrun: status->kind = no-resumed infrun: TARGET_WAITKIND_NO_RESUMED infrun: stop_waiting infrun: clear_step_over_info Sending packet: $qfThreadInfo#bb...Ack Packet received: m1 Sending packet: $qsThreadInfo#c8...Ack Packet received: l No unwaited-for children left. infrun: infrun_async(0) (gdb) c Continuing. Cannot execute this command while the selected thread is running. (gdb) Continuing. Cannot execute this command while the selected thread is running. This behavior shows up whenever GDB is in all-stop mode and is handling target-initiated File-I/O requests, in the middle of, say, a continue request. When GDB is done handling the File-I/O request, it doesn't set rs->waiting_for_stop_reply back to 1, meaning GDB should wait for further target events. This seems to be a latent bug, because in the past this didn't really cause any issues. But it seems to have been uncovered by commit 567420d10895611e03d5ee65e6b24c16a69a6e99, which explicitly checks for rs->waiting_for_stop_reply == 0, triggering the failures above. The following patch fixes this by reorganizing the setting of rs->waiting_for_stop_reply. infrun: prepare_to_wait Packet received: Ffstat,00000001,07fffdb0 Sending packet: $M7fffdb0,40:000000000000000000002080000000010000c336000001180000000000000000000000000000000000000200000000000000000055dfb19e55dfb19e55dfb19e#7b...Ack Packet received: OK Sending packet: $F0#76...Ack infrun: target_wait (-1.0.0, status) = infrun: -1.0.0 [Thread 0], infrun: status->kind = ignore infrun: TARGET_WAITKIND_IGNORE infrun: prepare_to_wait Packet received: Fisatty,00000001 Sending packet: $F1#77...Ack infrun: target_wait (-1.0.0, status) = infrun: -1.0.0 [Thread 0], infrun: status->kind = ignore infrun: TARGET_WAITKIND_IGNORE infrun: prepare_to_wait Packet received: Fwrite,00000001,0000d098,00000004 Sending packet: $md098,4#d2...Ack Packet received: 3732300a 720 Sending packet: $F4#7a...Ack infrun: target_wait (-1.0.0, status) = infrun: -1.0.0 [Thread 0], infrun: status->kind = ignore infrun: TARGET_WAITKIND_IGNORE infrun: prepare_to_wait Packet received: Fwrite,00000001,07ffffac,00000011 Sending packet: $m7ffffac,11#8e...Ack Packet received: 0a2a2a2a204558495420636f646520300a *** EXIT code 0 Regression-tested on Ubuntu x86-64 and qemu-system-based debugging for arm eabi. gdb/ChangeLog: 2015-10-16 Luis Machado * remote.c (remote_wait_as): Set rs->waiting_for_stop_reply to 0 when handling 'E', 'T', 'S', 'X' and 'W' packets. Do not set rs->waiting_for_stop_reply back to 1. --- gdb/ChangeLog | 6 ++++++ gdb/remote.c | 22 ++++++++-------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d0af780..7e6440b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2015-10-19 Luis Machado + + * remote.c (remote_wait_as): Set rs->waiting_for_stop_reply to 0 + when handling 'E', 'T', 'S', 'X' and 'W' packets. + Do not set rs->waiting_for_stop_reply back to 1. + 2015-10-16 Aleksandar Ristovski * nto-procfs.c (common/filestuff.h): Include. diff --git a/gdb/remote.c b/gdb/remote.c index f40f791..fed397a 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -6635,9 +6635,6 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options) rs->stop_reason = TARGET_STOPPED_BY_NO_REASON; - /* 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') @@ -6648,6 +6645,8 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options) case 'E': /* Error of some sort. */ /* We're out of sync with the target now. Did it continue or not? Not is more likely, so report a stop. */ + rs->waiting_for_stop_reply = 0; + warning (_("Remote failure reply: %s"), buf); status->kind = TARGET_WAITKIND_STOPPED; status->value.sig = GDB_SIGNAL_0; @@ -6658,7 +6657,12 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options) break; case 'T': case 'S': case 'X': case 'W': { - struct stop_reply *stop_reply + struct stop_reply *stop_reply; + + /* There is a stop reply to handle. */ + rs->waiting_for_stop_reply = 0; + + stop_reply = (struct stop_reply *) remote_notif_parse (¬if_client_stop, rs->buf); @@ -6667,10 +6671,6 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options) } case 'O': /* Console output. */ remote_console_output (buf + 1); - - /* The target didn't really stop; keep waiting. */ - rs->waiting_for_stop_reply = 1; - break; case '\0': if (rs->last_sent_signal != GDB_SIGNAL_0) @@ -6686,17 +6686,11 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options) strcpy ((char *) buf, rs->last_sent_step ? "s" : "c"); putpkt ((char *) buf); - - /* We just told the target to resume, so a stop reply is in - order. */ - rs->waiting_for_stop_reply = 1; break; } /* else fallthrough */ default: warning (_("Invalid remote reply: %s"), buf); - /* Keep waiting. */ - rs->waiting_for_stop_reply = 1; break; } -- 2.7.4