Re: [PATCH 7/9] Enqueue signal even when resuming threads

Pedro Alves
2016-07-01T16:55:30Z

On 07/01/2016 05:45 PM, Yao Qi wrote:

> You meant "after resuming it" rather than "before resuming it", right? We have
> two pending signals, so we resume the lwp and deliver the first signal. After
> resuming, we need to immediately deliver the second signal, so we call
> send_sigstop.

No, I really meant "before resuming it". We'd queue a SIGSTOP
in the kernel, and then resume the thread with
PTRACE_CONTINUE/STEP + signal. The idea being that the thread would
continue out of the signal delivery path in the kernel side with
the signal we resume it with, so if there's a signal handler,
it's what the kernel makes the thread execute as soon as it reaches
userspace. But given we had _also_ queued a SIGSTOP, the thread would
immediately report the SIGSTOP before it had a chance of executing the
first instruction of the handler. IOW, it'd report the SIGSTOP in
the first instruction of the handler, or where it was already
stopped before, if the signal signal passed to PTRACE_CONTINUE
is SIG_IGN.

Seeing the thread stop for a SIGSTOP that gdbserver had itself
sent, gdbserver would immediately re-resume the thread, this time,
with the other pending signal. This latter part probably already
works without any change. See tail end of linux_low_filter_event,
where we have:

if (WIFSTOPPED (wstat) && WSTOPSIG (wstat) == SIGSTOP
&& child->stop_expected)
{
if (debug_threads)
debug_printf ("Expected stop.\n");
child->stop_expected = 0;

> IIUC, this patch is OK as-is, right?
>

Yes.

Thanks,
Pedro Alves