[3/7] Avoid constant stream of TARGET_WAITKIND_NO_RESUMED

Message ID 20200706190252.22552-4-pedro@palves.net
State New
Headers show
  • GDB busy loop when interrupting non-stop program (PR 26199)
Related show

Commit Message

Pedro Alves July 6, 2020, 7:02 p.m.
If we hit the synchronous execution command case described by
handle_no_resumed, and handle_no_resumed determines that the event
should be ignored, because it found a thread that is executing, we end
up in prepare_to_wait.

There, if the current target is not registered in the event loop right
now, we call mark_infrun_async_event_handler.  With that event handler
marked, the event loop calls again into fetch_inferior_event, which
calls target_wait, which returns TARGET_WAITKIND_NO_RESUMED, and we
end up in handle_no_resumed, again ignoring the event and marking
infrun_async_event_handler.  The result is that GDB is now always
keeping the CPU 100% busy in this loop, even though it continues to be
able to react to input and to real target events, because we still go
through the event-loop.

The problem is that marking of the infrun_async_event_handler in
prepare_to_wait.  That is there to handle targets that don't support
asynchronous execution.  So the correct predicate is whether async
execution is supported, not whether the target is async right now.


	PR gdb/26199
	* infrun.c (prepare_to_wait): Check target_can_async_p instead of
 gdb/infrun.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)



diff --git a/gdb/infrun.c b/gdb/infrun.c
index 6b655d4430..a01e0969cb 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -8116,7 +8116,11 @@  prepare_to_wait (struct execution_control_state *ecs)
   ecs->wait_some_more = 1;
-  if (!target_is_async_p ())
+  /* If the target can't async, emulate it by marking the infrun event
+     handler such that as soon as we get back to the event-loop, we
+     immediately end up in fetch_inferior_event again calling
+     target_wait.  */
+  if (!target_can_async_p ())
     mark_infrun_async_event_handler ();