<div dir="ltr">Terribly sorry, didn't hit reply all... If i ever meet any of you folks i shall pay you a few of your favorite beverages. Original message:<div><br></div><div><span style="font-family:arial,sans-serif;font-size:13px">From an end-user perspective like mine, it's totally fine to piggy back on whatever stop event caused the process to halt and just set a flag on the event. It just needs to be documented a tiny bit better. Not a complaint at all, I'm probably not the average LLDB API user. I'd suspect most people using LLDB via the API know what they do :)</span><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px">Thanks for all the information!</div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Oct 27, 2014 at 7:31 PM, <span dir="ltr"><<a href="mailto:jingham@apple.com" target="_blank">jingham@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
> On Oct 27, 2014, at 11:02 AM, Greg Clayton <<a href="mailto:gclayton@apple.com">gclayton@apple.com</a>> wrote:<br>
><br>
>><br>
>> On Oct 26, 2014, at 5:23 AM, Mario Zechner <<a href="mailto:badlogicgames@gmail.com">badlogicgames@gmail.com</a>> wrote:<br>
>><br>
>> 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 :)<br>
>><br>
> Glad you figured this out, I was about to mention EINTR and handling those correctly.<br>
><br>
>> For question 1, i'd like to elaborate on the scenario:<br>
>><br>
>> - We have one event loop thread constantly polling events from the process via SBListener::WaitForEvent<br>
>> - 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.<br>
>> - 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.<br>
>><br>
>> 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:<br>
>><br>
>> 1) the process was already stopped -> Process::Halt returns immediately, no additional events are generated<br>
>> 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<br>
>> 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.<br>
>><br>
>> 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.[[<br>
><br>
> 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?<br>
><br>
> 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?<br>
<br>
</span>No, I don't think this is right. The thread that stopped at a breakpoint should not have its stop reason changed. That would be really confusing. I think it is better to mark the event with Interrupted, since that is really a process wide event, and the point is you don't really even know which action on which thread caused the eventual interruption. Indeed, there may be no thread specific action at all. For instance on Mac OS X we could decide to use the Mach "task_suspend" to interrupt processes instead of going through the signal mechanism at all. We don't do that because it leaves the process in a pretty shady state, whereas sending it a signal causes it to rendezvous in user space in a more consistent state. But we could do that and in that case you would interrupt the process but NO thread would have any specific reason. So again, this really needs to be an attribute on the stop event itself, not the stop reasons of individual threads.<br>
<br>
We could also introduce another stop event - an interrupted event - but right now the stop event handling is pretty simple, there's mostly just stopped, running, and exited, and any other information like restarted or interrupted are side-bits on the event that you can ask about if you need to know. Not sure I see any great advantage to changing that.<br>
<br>
I don't mind at some point going back and trying to cover over the Stop Reason for the thread that eventually stops. So if we knew we sent a SIGSTOP, and saw the thread with the SIGSTOP, might be okay to change this to a StopReason of interrupted. But of course you could have sent a SIGSTOP just as the program was getting a job control SIGSTOP, so you could still get this wrong...<br>
<br>
Jim<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
>><br>
>> Sorry for the wall of text. I feel my adventure notes here may serve others to navigate LLDB for similar use cases :)<br>
>><br>
>> Thanks,<br>
>> Mario<br>
>><br>
>> On Sun, Oct 26, 2014 at 11:59 AM, Mario Zechner <<a href="mailto:badlogicgames@gmail.com">badlogicgames@gmail.com</a>> wrote:<br>
>> 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.<br>
>><br>
>> Thanks,<br>
>> Mario<br>
>><br>
>> On Sun, Oct 26, 2014 at 11:56 AM, Mario Zechner <<a href="mailto:badlogicgames@gmail.com">badlogicgames@gmail.com</a>> wrote:<br>
>> Hi,<br>
>><br>
>> 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:<br>
>><br>
>> 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<br>
>> 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?<br>
>><br>
>> 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().<br>
>><br>
>> As always, thanks for all your help!<br>
>><br>
>> ciao,<br>
>> Mario<br>
>><br>
>><br>
>> _______________________________________________<br>
>> lldb-dev mailing list<br>
>> <a href="mailto:lldb-dev@cs.uiuc.edu">lldb-dev@cs.uiuc.edu</a><br>
>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev</a><br>
><br>
><br>
> _______________________________________________<br>
> lldb-dev mailing list<br>
> <a href="mailto:lldb-dev@cs.uiuc.edu">lldb-dev@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev</a><br>
<br>
</div></div></blockquote></div><br></div>