]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit
[gdb/dap] Fix stray KeyboardInterrupt after cancel
authorTom de Vries <tdevries@suse.de>
Thu, 29 Feb 2024 20:29:34 +0000 (21:29 +0100)
committerTom de Vries <tdevries@suse.de>
Thu, 29 Feb 2024 20:29:34 +0000 (21:29 +0100)
commit032d23a6db097840b7969867df0e2ba035f03f6f
tree134add30a5e3b11f5fed90c3e8b229f1fcbe62b6
parentfd09caf44f193fb4359376b27904bad0a16ca594
[gdb/dap] Fix stray KeyboardInterrupt after cancel

When running test-case gdb.dap/pause.exp 100 times in a loop, it passes
100/100.

But if we remove the two "sleep 0.2" from the test-case, we run into
(copied from dap.log and edited for readability):
...
Traceback (most recent call last):
  File "startup.py", line 251, in message
    def message():

KeyboardInterrupt
Quit
...

This happens as follows.

CancellationHandler.cancel calls gdb.interrupt to cancel a request in flight.

The idea is that this interrupt triggers while in fn here in message (a nested
function of send_gdb_with_response):
...
    def message():
        try:
            val = fn()
            result_q.put(val)
        except (Exception, KeyboardInterrupt) as e:
            result_q.put(e)
...
but instead it triggers outside the try/except.

Fix this by:
- in CancellationHandler, renaming variable in_flight to in_flight_dap_thread,
  and adding a variable in_flight_gdb_thread to be able to distinguish when
  a request is in flight in the dap thread or the gdb thread.
- adding a wrapper Cancellable to to deal with cancelling the wrapped
  event
- using Cancellable in send_gdb and send_gdb_with_response to wrap the posted
  event
- in CancellationHandler.cancel, only call gdb.interrupt if
  req == self.in_flight_gdb_thread.

This makes the test-case pass 100/100, also when adding the extra stressor of
"taskset -c 0", which makes the fail more likely without the patch.

Tested on aarch64-linux.

Approved-By: Tom Tromey <tom@tromey.com>
PR dap/31275
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31275
gdb/python/lib/gdb/dap/server.py