From a33d4569f12ccd88d0e848c6ace060a19241cf1e Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Mon, 6 Jul 2020 15:53:28 -0400 Subject: [PATCH] gdb: defer commit resume until all available events are consumed This patch makes GDB defer commit resume when handling a sequence of target events. In fetch_inferior_event, a scoped_restore object is instantiated (if it's not already) to set the defer_commit_resume flag. Any resumption that is the result of handling that event will therefore not be committed. If there are other events immediatly consumable, they'll all be handled while the "defer commit resume flag" is set. Once do_target_wait returns false, we know that we have consumed all immediatly available events, then the "defer commit resume" flag is reset and a commit resume is issued. After having handled an event in fetch_inferior_event, we call mark_infrun_async_event_handler to make sure that fetch_inferior_event gets called at least once more, to get that final call where do_target_wait returns no event. Change-Id: I18112ba19a1ff4986530c660f530d847bb4a1f1d --- gdb/infrun.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/gdb/infrun.c b/gdb/infrun.c index ad7ff7f1a8..a702940a72 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -3889,9 +3889,19 @@ fetch_inferior_event () = make_scoped_restore (&execution_direction, target_execution_direction ()); + /* Hold the resume commands until we are done consuming all immediately + available target events. */ + static gdb::optional> restore_defer_commit_resume; + if (!restore_defer_commit_resume.has_value ()) + restore_defer_commit_resume.emplace (make_scoped_defer_target_commit_resume ()); + if (!do_target_wait (minus_one_ptid, ecs, TARGET_WNOHANG)) { infrun_log_debug ("do_target_wait returned false"); + + /* No more events to process, let the resume commands free. */ + restore_defer_commit_resume.reset (); + commit_resume_all_targets(); return; } @@ -3991,6 +4001,8 @@ fetch_inferior_event () /* No error, don't finish the thread states yet. */ finish_state.release (); + mark_infrun_async_event_handler (); + /* This scope is used to ensure that readline callbacks are reinstalled here. */ } -- 2.34.1