Fix bug in DAP handling of 'pause' requests

While working on cancellation, I noticed that a DAP 'pause' request
would set the "do not emit the continue" flag.  This meant that a
subsequent request that should provoke a 'continue' event would
instead suppress the event.

I then tried writing a more obvious test case for this, involving an
inferior call -- and discovered that gdb.events.cont does not fire for
an inferior call.

This patch installs a new event listener for gdb.events.inferior_call
and arranges for this to emit continue and stop events when
appropriate.  It also fixes the original bug, by adding a check to
exec_and_expect_stop.

(cherry picked from commit c618a1c548193d2a6a8c3d909a3d1c620a156b5d)
This commit is contained in:
Tom Tromey
2023-11-17 10:08:50 -07:00
parent 5a37e5855c
commit fb2d9542d0
3 changed files with 97 additions and 3 deletions

View File

@ -128,8 +128,9 @@ def exec_and_expect_stop(cmd, reason):
"""Indicate that a stop is expected, then execute CMD"""
global _expected_stop
_expected_stop = reason
global _suppress_cont
_suppress_cont = True
if reason != StopKinds.PAUSE:
global _suppress_cont
_suppress_cont = True
# FIXME if the call fails should we clear _suppress_cont?
exec_and_log(cmd)
@ -156,6 +157,26 @@ def _on_stop(event):
send_event("stopped", obj)
# This keeps a bit of state between the start of an inferior call and
# the end. If the inferior was already running when the call started
# (as can happen if a breakpoint condition calls a function), then we
# do not want to emit 'continued' or 'stop' events for the call. Note
# that, for some reason, gdb.events.cont does not fire for an infcall.
_infcall_was_running = False
@in_gdb_thread
def _on_inferior_call(event):
global _infcall_was_running
if isinstance(event, gdb.InferiorCallPreEvent):
_infcall_was_running = inferior_running
if not _infcall_was_running:
_cont(None)
else:
if not _infcall_was_running:
_on_stop(None)
gdb.events.stop.connect(_on_stop)
gdb.events.exited.connect(_on_exit)
gdb.events.new_thread.connect(_new_thread)
@ -163,3 +184,4 @@ gdb.events.thread_exited.connect(_thread_exited)
gdb.events.cont.connect(_cont)
gdb.events.new_objfile.connect(_new_objfile)
gdb.events.free_objfile.connect(_objfile_removed)
gdb.events.inferior_call.connect(_on_inferior_call)