Sorry for the mail bomb. After some more investigation, it's the inferior's responsibility to deal with SIGSTOP itself, e.g. interpret and act upon errno == EINTR. Lucky, our runtime library already seems to take care of EINTR properly and supports "restartable" I/O. So i guess i answered question 2 myself. Progress
Glad you figured this out, I was about to mention EINTR and handling those correctly.
For question 1, i'd like to elaborate on the scenario:
- We have one event loop thread constantly polling events from the process via SBListener::WaitForEvent
- We setup a few breakpoints in our runtime to get to know about things like thread creation/death and so on. When such a "hook" breakpoint is hit, we read whatever information we need from the inferior and then automatically resume the process via SBProcess:Continue. All this happens on the event loop thread, in response to breakpoint stop events with the appropriate location.
- We have a second thread, let's call it JDWP thread, that listens for JDWP commands. When a command arrives, we need to stop the inferior, perform the command, and resume the inferior. For this we temporarily disable the event loop thread (no more calls to WaitForEvent, hence no "Hook" breakpoint processing, hence no calls to SBProcess::Continue on the event loop thread), call SBProcess::Stop(), perform our command, call SBProcess::Continue and then reenable the event loop thread.
This setup has one issue, which relates to my first question (stop/breakpoint event taken over by SBProcess::Halt and marked as interrupted). When we stop the event loop thread and then call SBProcess::Stop(), one of three things can happen:
1) the process was already stopped -> Process::Halt returns immediately, no additional events are generated
2) the process wasn't stopped yet, so Process::Halt sends SIGSTOP and an event with stop reason eStopReasonSignal will eventually be generated and broadcast to the SBListener in the event loop thread
3) the process wasn't stopped yet, while Process::Halt does its thing a stop event arrives (e.g. breakpoint) and is consumed by Process::Halt. Process::Halt takes over that event, marks it as interrupted then rebroadcasts it.
In case 3 (breakpoint event is taken over and marked) we don't want to automatically resume the process. That's why we need to be able to decipher if the event was marked as interrupted, so we can decide whether the JDWP thread should actually resume the process once its done responding to the JDWP request.
An easy way to deal with this is to take the race out by having your event thread do the resume and don't have your breakpoint do the auto resume. More generically, we do need LLDB to be able stop the auto-resume stuff from happening. To clarify your case #3 above: you are still getting a stop event, just not a eStopReasonSignal? No stop reason?
If a plug-in sends a "SIGSTOP" in order to stop a process, we really should be not showing that to the user as the reason for the stop like we are now, we should be covering it up and giving a new eStopReasonInterrupted for a thread instead IMHO. If we did this, would this clear up your issues?