Skip to content

Commit a6f5154

Browse files
committed
fbsd-nat: Defer any ineligible events reported by wait.
If wait_1 finds an event for a thread or process that does not match the set of threads and processes previously resumed, defer the event. If the event is for a specific thread, suspend the thread and continue the associated process before waiting for another event. One specific example of such an event is if a thread is created while another thread in the same process hits a breakpoint. If the second thread's event is reported first, the target resume method does not yet "know" about the new thread and will not suspend it via PT_SUSPEND. When wait is called, it will probably return the event from the first thread before the result of the step from second thread. This is the case reported in PR 21497. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=21497
1 parent 1b0fa45 commit a6f5154

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

gdb/fbsd-nat.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1486,7 +1486,40 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
14861486
if (is_async_p ())
14871487
async_file_flush ();
14881488

1489-
ptid_t wptid = wait_1 (ptid, ourstatus, target_options);
1489+
ptid_t wptid;
1490+
while (1)
1491+
{
1492+
wptid = wait_1 (ptid, ourstatus, target_options);
1493+
1494+
/* If no event was found, just return. */
1495+
if (ourstatus->kind () == TARGET_WAITKIND_IGNORE
1496+
|| ourstatus->kind () == TARGET_WAITKIND_NO_RESUMED)
1497+
break;
1498+
1499+
/* If an event is reported for a thread or process while
1500+
stepping some other thread, suspend the thread reporting the
1501+
event and defer the event until it can be reported to the
1502+
core. */
1503+
if (!wptid.matches (m_resume_ptid))
1504+
{
1505+
add_pending_event (wptid, *ourstatus);
1506+
fbsd_nat_debug_printf ("deferring event [%s], [%s]",
1507+
target_pid_to_str (wptid).c_str (),
1508+
ourstatus->to_string ().c_str ());
1509+
if (wptid.pid () == m_resume_ptid.pid ())
1510+
{
1511+
fbsd_nat_debug_printf ("suspending thread [%s]",
1512+
target_pid_to_str (wptid).c_str ());
1513+
if (ptrace (PT_SUSPEND, wptid.lwp (), NULL, 0) == -1)
1514+
perror_with_name (("ptrace (PT_SUSPEND)"));
1515+
if (ptrace (PT_CONTINUE, wptid.pid (), (caddr_t) 1, 0) == -1)
1516+
perror_with_name (("ptrace (PT_CONTINUE)"));
1517+
}
1518+
continue;
1519+
}
1520+
1521+
break;
1522+
}
14901523

14911524
/* If we are in async mode and found an event, there may still be
14921525
another event pending. Trigger the event pipe so that that the

0 commit comments

Comments
 (0)