[lldb-dev] Stop/Resume process, interrupting I/O

Greg Clayton gclayton at apple.com
Mon Oct 27 11:02:55 PDT 2014


> On Oct 26, 2014, at 5:23 AM, Mario Zechner <badlogicgames at gmail.com> wrote:
> 
> 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?
> 
> Sorry for the wall of text. I feel my adventure notes here may serve others to navigate LLDB for similar use cases :)
> 
> Thanks,
> Mario
> 
> On Sun, Oct 26, 2014 at 11:59 AM, Mario Zechner <badlogicgames at gmail.com> wrote:
> Just to clarify my use of "interrupted". Of course all threads should be stopped upon SBProcess::Stop(). However, upon SBProcess:Resume() I/O operations shouldn't just return due to the SIGSTOP but continue doing what they did before receiving the signal.
> 
> Thanks,
> Mario
> 
> On Sun, Oct 26, 2014 at 11:56 AM, Mario Zechner <badlogicgames at gmail.com> wrote:
> Hi,
> 
> i'm currently trying to understand how LLDB interrupts/resumes processes. To my understanding, the Process implementation sends a SIGSTOP to the inferior, which will stop the process. Alternatively, the process may be stopped (e.g. breakpoint) while Process::DoHalt is executing, in which case the event is marked as interrupted. I have a few questions regarding this:
> 
> 1) How can i check wether an event was marked as interrupted via the API? SBProcess has a couple of static methods like GetStateFromEvent, but none of these allow me to check if the event was marked as interrupted
> 2) SIGSTOP seems to interrupt any I/O call, e.g. getchar, listen, and so on. Upon a resume, these functions will simply return (e.g. returning EOF) instead of continuing waiting for input. Is there any way to have this not happen?
> 
> Our problem is, that we need to stop/resume the process to implement parts of JDWP (Java debugging wire protocol). Some JDWP commands require us to stop the process, read some memory regions and resume the process again, letting the inferior think that nothing has happened. All of this should not interfere with normal program execution, e.g. a file read shouldn't be interrupted because we stopped the inferior via SBProcess:Stop().
> 
> As always, thanks for all your help!
> 
> ciao,
> Mario
> 
> 
> _______________________________________________
> lldb-dev mailing list
> lldb-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev





More information about the lldb-dev mailing list