diff options
author | Pedro Alves <pedro@palves.net> | 2020-07-04 19:26:59 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2020-07-06 19:57:46 +0100 |
commit | 85dae3461286b416a19c7ab53681786be6965cc0 (patch) | |
tree | 30c6d737ce0c6c517563a1fd466e32134c281517 | |
parent | f7bf4732bb5a8d2b27c3ab7428f359481cffe970 (diff) | |
download | gdb-85dae3461286b416a19c7ab53681786be6965cc0.zip gdb-85dae3461286b416a19c7ab53681786be6965cc0.tar.gz gdb-85dae3461286b416a19c7ab53681786be6965cc0.tar.bz2 |
Fix handle_no_resumed w/ multiple targets
handle_no_resumed is currently not considering multiple targets.
Say you have two inferiors 1 and 2, each connected to a different
target, A and B.
Now say you set inferior 2 running, with "continue &".
Now you select a thread of inferior 1, say thread 1.2, and continue in
the foreground. All other threads of inferior 1 are left stopped.
Thread 1.2 exits, and thus target A has no other resumed thread, so it
reports TARGET_WAITKIND_NO_RESUMED.
At this point, if both inferiors were running in the same target,
handle_no_resumed would realize that threads of inferior 2 are still
executing, so the TARGET_WAITKIND_NO_RESUMED event should be ignored.
But because handle_no_resumed only walks the threads of the current
target, it misses noticing that threads of inferior 2 are still
executing. The fix is just to walk over all threads of all targets.
A testcase covering the use case above will be added in a following
patch. It can't be added yet because it depends on yet another fix to
handle_no_resumed not included here.
gdb/ChangeLog:
PR gdb/26199
* infrun.c (handle_no_resumed): Handle multiple targets.
-rw-r--r-- | gdb/infrun.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c index a01e096..0f2f45a 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -5068,16 +5068,28 @@ handle_no_resumed (struct execution_control_state *ecs) have resumed threads _now_. In the example above, this removes thread 3 from the thread list. If thread 2 was re-resumed, we ignore this event. If we find no thread resumed, then we cancel - the synchronous command show "no unwaited-for " to the user. */ - update_thread_list (); + the synchronous command and show "no unwaited-for " to the + user. */ + + { + scoped_restore_current_thread restore_thread; + + for (auto *target : all_non_exited_process_targets ()) + { + switch_to_target_no_thread (target); + update_thread_list (); + } + } - for (thread_info *thread : all_non_exited_threads (ecs->target)) + for (thread_info *thread : all_non_exited_threads ()) { if (thread->executing || thread->suspend.waitstatus_pending_p) { - /* There were no unwaited-for children left in the target at - some point, but there are now. Just ignore. */ + /* Either there were no unwaited-for children left in the + target at some point, but there are now, or some target + other than the eventing one has unwaited-for children + left. Just ignore. */ if (debug_infrun) fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_RESUMED " |