diff options
author | Pedro Alves <palves@redhat.com> | 2015-02-03 16:07:54 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2015-02-03 16:14:45 +0100 |
commit | b7d2e91626b0e587f3fd5023e79b5079da6baed5 (patch) | |
tree | b97ddb08694bae8faf46687b57101cd99890bf2a /gdb/remote.c | |
parent | d9d41e786a077db1b536b1124af6e135b9ad46a0 (diff) | |
download | gdb-b7d2e91626b0e587f3fd5023e79b5079da6baed5.zip gdb-b7d2e91626b0e587f3fd5023e79b5079da6baed5.tar.gz gdb-b7d2e91626b0e587f3fd5023e79b5079da6baed5.tar.bz2 |
When disabling target async, remove all target event sources from the event loop
The sigall-reverse.exp test occasionally fails with something like this:
(gdb) PASS: gdb.reverse/sigall-reverse.exp: send signal TERM
continue
Continuing.
The next instruction is syscall exit_group. It will make the program exit. Do you want to stop the program?([y] or n) FAIL: gdb.reverse/sigall-reverse.exp: continue to signal exit (timeout)
FAIL: gdb.reverse/sigall-reverse.exp: reverse to handler of TERM (timeout)
FAIL: gdb.reverse/sigall-reverse.exp: reverse to gen_TERM (timeout)
This is another event-loop/async related problem exposed by the patch
that made 'query' use gdb_readline_wrapper (588dcc3edbde19f9).
The problem is that even though gdb_readline_wrapper disables
target-async while the secondary prompt is in progress, the record
target's async event source is left marked. So when
gdb_readline_wrapper nests an event loop to process input, it may
happen that that event loop ends up processing a target event while
GDB is not really ready for it. Here's the relevant part of the
backtrace showing the root issue in action:
...
#14 0x000000000061cb48 in fetch_inferior_event (client_data=0x0) at src/gdb/infrun.c:4158
#15 0x0000000000642917 in inferior_event_handler (event_type=INF_REG_EVENT, client_data=0x0) at src/gdb/inf-loop.c:57
#16 0x000000000077ca5c in record_full_async_inferior_event_handler (data=0x0) at src/gdb/record-full.c:791
#17 0x0000000000640fdf in invoke_async_event_handler (data=...) at src/gdb/event-loop.c:1067
#18 0x000000000063fb01 in process_event () at src/gdb/event-loop.c:339
#19 0x000000000063fb2a in gdb_do_one_event () at src/gdb/event-loop.c:360
#20 0x000000000074d607 in gdb_readline_wrapper (prompt=0x3588f40 "The next instruction is syscall exit_group. It will make the program exit. Do you want to stop the program?([y] or n) ") at src/gdb/top.c:842
#21 0x0000000000750bd9 in defaulted_query (ctlstr=0x8c6588 "The next instruction is syscall exit_group. It will make the program exit. Do you want to stop the program?", defchar=121 'y', args=0x7fff70524410) at src/gdb/utils.c:1279
#22 0x0000000000750e4c in yquery (ctlstr=0x8c6588 "The next instruction is syscall exit_group. It will make the program exit. Do you want to stop the program?") at src/gdb/utils.c:1358
#23 0x00000000004b020e in record_linux_system_call (syscall=gdb_sys_exit_group, regcache=0x3529450, tdep=0xd6c840 <amd64_linux_record_tdep>) at src/gdb/linux-record.c:1933
With my all-stop-on-top-of-non-stop series, I'm also seeing
gdb.server/ext-attach.exp fail occasionally due to the same issue.
The first part of the fix is for target_async implementations to make
sure to remove/unmark all target-related event sources from the event
loop.
Tested on x86_64 Fedora 20, native and gdbserver.
gdb/
2015-02-03 Pedro Alves <palves@redhat.com>
* event-loop.c (clear_async_event_handler): New function.
* event-loop.h (clear_async_event_handler): New declaration.
* record-btrace.c (record_btrace_async): New function.
(init_record_btrace_ops): Install record_btrace_async.
* record-full.c (record_full_async): New function.
(record_full_resume): Don't mark the async event source here.
(init_record_full_ops): Install record_full_async.
(record_full_core_resume): Don't mark the async event source here.
(init_record_full_core_ops): Install record_full_async.
* remote.c (remote_async): Mark and clear the async stop reply
queue event-loop token as appropriate.
Diffstat (limited to 'gdb/remote.c')
-rw-r--r-- | gdb/remote.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/gdb/remote.c b/gdb/remote.c index 9be15cb..e971a29 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -11691,9 +11691,17 @@ remote_async (struct target_ops *ops, serial_async (rs->remote_desc, remote_async_serial_handler, rs); rs->async_client_callback = callback; rs->async_client_context = context; + + /* If there are pending events in the stop reply queue tell the + event loop to process them. */ + if (!QUEUE_is_empty (stop_reply_p, stop_reply_queue)) + mark_async_event_handler (remote_async_inferior_event_token); } else - serial_async (rs->remote_desc, NULL, NULL); + { + serial_async (rs->remote_desc, NULL, NULL); + clear_async_event_handler (remote_async_inferior_event_token); + } } static void |