When a debugger attaches to the process, SIGSTOP is sent to the target. Due to way issignal() selects the next signal to deliver and report, if the simultaneous or already pending another signal exists, that signal will be reported by next waitpid(2). This causes minor annoyance for debuggers, which must be prepared to take any signal as the first event, then filter SIGSTOP later.
More importantly, for tools like gcore(1), which attach and then detach without processing events, SIGSTOP might leak to be delivered after PT_DETACH. AFAIK, this was the situation which bitten Mark.
The solution is to force SIGSTOP to be the first signal reported after the attach. Attach code sets P2_PTRACE_FSTP to indicate that the attaching ritual was not yet finished, and issignal() prefers SIGSTOP in that condition. Also, the thread which handles P2_PTRACE_FSTP is made to guarantee to own p_xthread during the first waitpid(2). All that ensures that SIGSTOP is consumed first.
Additionally, if P2_PTRACE_FSTP is still set on detach, which means that waitpid(2) was not called at all, SIGSTOP is removed from the queue, ensuring that the process is resumed on detach.
In issignal(), when acting on STOPing signals, remove the signal from queue before suspending. Otherwise parallel attach could
result in ptracestop() acting on that STOP as if it was the STOP signal from the attach. Then SIGSTOP from attach leaks again.
As a minor refactoring, some bits of the common attach code is moved to proc_set_traced().