summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <pedro@palves.net>2020-07-04 19:26:59 +0100
committerPedro Alves <palves@redhat.com>2020-07-06 19:57:46 +0100
commit85dae3461286b416a19c7ab53681786be6965cc0 (patch)
tree30c6d737ce0c6c517563a1fd466e32134c281517
parentf7bf4732bb5a8d2b27c3ab7428f359481cffe970 (diff)
downloadbinutils-gdb-85dae3461286b416a19c7ab53681786be6965cc0.tar.gz
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.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c
index a01e0969cb1..0f2f45a4d2d 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 "