auto do_wait = [&] (inferior *inf)
{
- ecs->ptid = do_target_wait_1 (inf, wait_ptid, &ecs->ws, options);
+ ptid_t ptid { inf->pid };
+
+ /* Make sure we're not widening WAIT_PTID. */
+ if (!ptid.matches (wait_ptid)
+ /* Targets that cannot async will be asked for a blocking wait.
+
+ Blocking wait does not work inferior-by-inferior if the target
+ provides more than one inferior. Fall back to waiting for
+ WAIT_PTID in that case. */
+ || !target_can_async_p () || ((options & TARGET_WNOHANG) == 0)
+ /* We cannot wait for inferiors without a pid.
+
+ One such inferior is created by initialize_inferiors () to
+ ensure that there always is an inferior. */
+ || !ptid.is_pid ())
+ ptid = wait_ptid;
+
+ ecs->ptid = do_target_wait_1 (inf, ptid, &ecs->ws, options);
ecs->target = inf->process_target ();
return (ecs->ws.kind () != TARGET_WAITKIND_IGNORE);
};
reported the stop to the user, polling for events. */
scoped_restore_current_thread restore_thread;
+ /* The first TARGET_WAITKIND_NO_RESUMED execution state.
+
+ We do not want to return TARGET_WAITKIND_NO_RESUMED right away since
+ another inferior may have a more interesting event to report. If
+ there is no other event to report, after all, we want to report the
+ first such event.
+
+ This variable holds that first event, which will be copied on the
+ first TARGET_WAITKIND_NO_RESUMED below. */
+ execution_control_state no_resumed {};
+ no_resumed.ptid = null_ptid;
+
intrusive_list_iterator<inferior> start
= inferior_list.iterator_to (*selected);
inferior *inf = &*it;
if (inferior_matches (inf) && do_wait (inf))
- return true;
+ {
+ if (ecs->ws.kind () != TARGET_WAITKIND_NO_RESUMED)
+ return true;
+
+ if (no_resumed.ptid == null_ptid)
+ no_resumed = *ecs;
+ }
}
for (intrusive_list_iterator<inferior> it = inferior_list.begin ();
inferior *inf = &*it;
if (inferior_matches (inf) && do_wait (inf))
- return true;
+ {
+ if (ecs->ws.kind () != TARGET_WAITKIND_NO_RESUMED)
+ return true;
+
+ if (no_resumed.ptid == null_ptid)
+ no_resumed = *ecs;
+ }
+ }
+
+ if (no_resumed.ptid != null_ptid)
+ {
+ *ecs = no_resumed;
+ return true;
}
ecs->ws.set_ignore ();
/* Add the initial process as the first LWP to the list. */
lp = add_initial_lwp (ptid);
+ lp->last_resume_kind = resume_stop;
status = linux_nat_post_attach_wait (lp->ptid, &lp->signalled);
if (!WIFSTOPPED (status))
moment at which we know its PID. */
if (ptid.is_pid () && find_lwp_pid (ptid) == nullptr)
{
- ptid_t lwp_ptid (ptid.pid (), ptid.pid ());
+ /* Unless we already did and this is simply a request to wait for a
+ particular inferior. */
+ inferior *inf = find_inferior_ptid (linux_target, ptid);
+ if ((inf != nullptr) && (inf->find_thread (ptid) != nullptr))
+ {
+ ptid_t lwp_ptid (ptid.pid (), ptid.pid ());
- /* Upgrade the main thread's ptid. */
- thread_change_ptid (linux_target, ptid, lwp_ptid);
- lp = add_initial_lwp (lwp_ptid);
- lp->resumed = 1;
+ /* Upgrade the main thread's ptid. */
+ thread_change_ptid (linux_target, ptid, lwp_ptid);
+ lp = add_initial_lwp (lwp_ptid);
+ lp->resumed = 1;
+ }
}
/* Make sure SIGCHLD is blocked until the sigsuspend below. */
{
remote_state *rs = get_remote_state ();
+ auto pred = [=] (const stop_reply_up &event)
+ {
+ /* A null ptid should only happen if we have a single process. It
+ wouldn't match the process ptid, though, so let's check this case
+ separately. */
+ if ((event->ptid == null_ptid) && ptid.is_pid ())
+ return true;
+
+ /* A minus one ptid should only happen for events that match
+ everything. It wouldn't match a process or thread ptid, though, so
+ let's check this case separately. */
+ if (event->ptid == minus_one_ptid)
+ return true;
+
+ return event->ptid.matches (ptid);
+ };
auto iter = std::find_if (rs->stop_reply_queue.begin (),
- rs->stop_reply_queue.end (),
- [=] (const stop_reply_up &event)
- {
- return event->ptid.matches (ptid);
- });
+ rs->stop_reply_queue.end (), pred);
stop_reply_up result;
if (iter != rs->stop_reply_queue.end ())
{