Make GDB wait for events after handling target File-I/O
authorLuis Machado <lgustavo@codesourcery.com>
Mon, 19 Oct 2015 13:33:19 +0000 (11:33 -0200)
committerLuis Machado <lgustavo@codesourcery.com>
Mon, 19 Oct 2015 13:36:01 +0000 (11:36 -0200)
_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  <lgustavo@codesourcery.com>

* 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
gdb/remote.c

index d0af780d03e266e0ca95ad3867ec534bf788a9f1..7e6440b6ae6111750d96b90e9176452290ba9e09 100644 (file)
@@ -1,3 +1,9 @@
+2015-10-19  Luis Machado  <lgustavo@codesourcery.com>
+
+       * 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  <aristovski@qnx.com>
 
        * nto-procfs.c (common/filestuff.h): Include.
index f40f79160fca6b0a03e3300481dcea10e0d9e584..fed397affeabe1e0716324bebd9fb4db7f91bebd 100644 (file)
@@ -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 (&notif_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;
     }