This is the mail archive of the
gdb-testers@sourceware.org
mailing list for the GDB project.
[binutils-gdb] Fix signal handler/event-loop races
- From: sergiodj+buildbot at sergiodj dot net
- To: gdb-testers at sourceware dot org
- Date: Tue, 12 Apr 2016 16:39:50 -0400
- Subject: [binutils-gdb] Fix signal handler/event-loop races
- Authentication-results: sourceware.org; auth=none
*** TEST RESULTS FOR COMMIT 5cc3ce8b5fffa7413557b7e071d8471ae6e2fc88 ***
Author: Pedro Alves <palves@redhat.com>
Branch: master
Commit: 5cc3ce8b5fffa7413557b7e071d8471ae6e2fc88
Fix signal handler/event-loop races
GDB's core signal handling suffers from a classical signal handler /
mainline code race:
int
gdb_do_one_event (void)
{
...
/* First let's see if there are any asynchronous signal handlers
that are ready. These would be the result of invoking any of the
signal handlers. */
if (invoke_async_signal_handlers ())
return 1;
...
/* Block waiting for a new event. (...). */
if (gdb_wait_for_event (1) < 0)
return -1;
...
}
If a signal is delivered while gdb is blocked in the poll/select
inside gdb_wait_for_event, then the select/poll breaks with EINTR,
we'll loop back around and call invoke_async_signal_handlers.
However, if the signal handler runs between
invoke_async_signal_handlers and gdb_wait_for_event,
gdb_wait_for_event will block, until the next unrelated event...
The fix is to a struct serial_event, and register it in the set of
files that select/poll in gdb_wait_for_event waits on. The signal
handlers that defer work to invoke_async_signal_handlers call
mark_async_signal_handler, which is adjusted to also set the new
serial event in addition to setting a flag, and is thus now is
garanteed to immediately unblock the next gdb_select/poll call, up
until invoke_async_signal_handlers is called and the event is cleared.
gdb/ChangeLog:
2016-04-12 Pedro Alves <palves@redhat.com>
* event-loop.c: Include "ser-event.h".
(async_signal_handlers_serial_event): New global.
(async_signals_handler, initialize_async_signal_handlers): New
functions.
(mark_async_signal_handler): Set
async_signal_handlers_serial_event.
(invoke_async_signal_handlers): Clear
async_signal_handlers_serial_event.
* event-top.c (async_init_signals): Call
initialize_async_signal_handlers.