+2014-05-29 Pedro Alves <palves@redhat.com>
+
+ PR gdb/15713
+ * linux-nat.c (linux_nat_resume_callback): Rename the second
+ parameter to 'except'. Skip LP if it points to EXCEPT.
+ (linux_nat_resume): Don't mark the event lwp as not stopped
+ before resuming sibling lwps. Instead ask
+ linux_nat_resume_callback to skip the event lwp. Mark it as not
+ stopped after actually resuming it.
+ (linux_handle_syscall_trap): Mark the lwp as not stopped after
+ resuming it.
+ (wait_lwp): Mark the lwp as stopped here.
+ (stop_wait_callback): Mark the lwp as not stopped right after
+ resuming it. Don't mark lwps as stopped here.
+ (linux_nat_filter_event): Mark the lwp as stopped earlier.
+ (linux_nat_wait_1): Don't mark dead lwps as stopped here.
+
2014-05-29 Pedro Alves <palves@redhat.com>
PR PR15693
}
}
-/* Resume LWP, with the last stop signal, if it is in pass state. */
+/* Callback for iterate_over_lwps. If LWP is EXCEPT, do nothing.
+ Resume LWP with the last stop signal, if it is in pass state. */
static int
-linux_nat_resume_callback (struct lwp_info *lp, void *data)
+linux_nat_resume_callback (struct lwp_info *lp, void *except)
{
enum gdb_signal signo = GDB_SIGNAL_0;
+ if (lp == except)
+ return 0;
+
if (lp->stopped)
{
struct thread_info *thread;
return;
}
- /* Mark LWP as not stopped to prevent it from being continued by
- linux_nat_resume_callback. */
- lp->stopped = 0;
-
if (resume_many)
- iterate_over_lwps (ptid, linux_nat_resume_callback, NULL);
+ iterate_over_lwps (ptid, linux_nat_resume_callback, lp);
/* Convert to something the lower layer understands. */
ptid = pid_to_ptid (ptid_get_lwp (lp->ptid));
linux_nat_prepare_to_resume (lp);
linux_ops->to_resume (linux_ops, ptid, step, signo);
lp->stopped_by_watchpoint = 0;
+ lp->stopped = 0;
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
lp->syscall_state = TARGET_WAITKIND_IGNORE;
ptrace (PTRACE_CONT, ptid_get_lwp (lp->ptid), 0, 0);
+ lp->stopped = 0;
return 1;
}
linux_nat_prepare_to_resume (lp);
linux_ops->to_resume (linux_ops, pid_to_ptid (ptid_get_lwp (lp->ptid)),
lp->step, GDB_SIGNAL_0);
+ lp->stopped = 0;
return 1;
}
linux_ops->to_resume (linux_ops,
pid_to_ptid (ptid_get_lwp (lp->ptid)),
0, GDB_SIGNAL_0);
-
+ lp->stopped = 0;
return 1;
}
}
gdb_assert (WIFSTOPPED (status));
+ lp->stopped = 1;
/* Handle GNU/Linux's syscall SIGTRAPs. */
if (WIFSTOPPED (status) && WSTOPSIG (status) == SYSCALL_SIGTRAP)
errno = 0;
ptrace (PTRACE_CONT, ptid_get_lwp (lp->ptid), 0, 0);
+ lp->stopped = 0;
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
"PTRACE_CONT %s, 0, 0 (%s) "
/* Save the sigtrap event. */
lp->status = status;
- gdb_assert (!lp->stopped);
gdb_assert (lp->signalled);
- lp->stopped = 1;
}
else
{
"SWC: Delayed SIGSTOP caught for %s.\n",
target_pid_to_str (lp->ptid));
- lp->stopped = 1;
-
/* Reset SIGNALLED only after the stop_wait_callback call
above as it does gdb_assert on SIGNALLED. */
lp->signalled = 0;
if (!WIFSTOPPED (status) && !lp)
return NULL;
+ /* This LWP is stopped now. (And if dead, this prevents it from
+ ever being continued.) */
+ lp->stopped = 1;
+
/* Handle GNU/Linux's syscall SIGTRAPs. */
if (WIFSTOPPED (status) && WSTOPSIG (status) == SYSCALL_SIGTRAP)
{
used. */
if (ptid_get_pid (lp->ptid) == ptid_get_lwp (lp->ptid))
{
- lp->stopped = 1;
iterate_over_lwps (pid_to_ptid (ptid_get_pid (lp->ptid)),
stop_and_resume_callback, new_pending_p);
}
" cancelled it\n",
ptid_get_lwp (lp->ptid));
}
- lp->stopped = 1;
}
else
- {
- lp->stopped = 1;
- lp->signalled = 0;
- }
+ lp->signalled = 0;
}
else if (WIFEXITED (lp->status) || WIFSIGNALED (lp->status))
{
pending for the next time we're able to report
it. */
- /* Prevent trying to stop this thread again. We'll
- never try to resume it because it has a pending
- status. */
- lp->stopped = 1;
-
/* Dead LWP's aren't expected to reported a pending
sigstop. */
lp->signalled = 0;