<div dir="ltr">And one more reply that didn't go to the list. Really sorry :/. Original message, plus an edit:<div><br></div><div><span style="font-family:arial,sans-serif;font-size:13px">The piggy backing of events is fine from my point of view as long as i can check the interrupted flag (for which i'll try to compose a patch). My issues stem more from the fact that i have to concurrently operate on the process (event loop thread, JDWP thread). The "hook" breakpoints are actually handled on the event loop thread, including the auto-resume, which is a requirement for our JDWP implementation to work correctly. The JDWP client shouldn't know that the process hit a "hook" breakpoint.</span><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px">My problem is really this: the JDWP thread stops the event loop thread. Next it stops the process via SBProcess::Stop (which calls Process::Halt). Sadly, Process::Halt doesn't set the state on the process. I have to poll events on the JDWP thread for that to happen, on the JDWP thread, until i get a stopped (or exited/crashed/...) event. I then have to re-broadcast those events so the event loop thread can later process them once i resume it. I'm very worried about re-broadcasting events as i don't know what havoc that will wreck in the LLDB internal state.</div><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px">Ideally, Process::Halt (and hence SBProcess::Stop()) would set things up in a way where i don't have to poll events on the JDWP thread. It should also set the process state accordingly. I also noticed strange timing bugs when calling SBProcess::Stop() while a previous SBProcess::Continue() is still being propagated to the inferior. That's actually what causes the eStopReasonInvalid events i talked about in another thread.</div><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px">I just played around with the Python API. Turns out i've been using SBListener::WaitForEvent incorrectly. I supplied 0 for timeout, assuming it would return immediately. This actually throws an assertion when called via the Python API. Our JNI wrapper of LLDB doesn't throw an assert. I guess SBListener::PeekAtNextEvent is what i should use instead for non-blocking event processing?</div><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px">As always, really appreciate that you take the time to read and answer my walls of text.</div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Oct 27, 2014 at 7:02 PM, Greg Clayton <span dir="ltr"><<a href="mailto:gclayton@apple.com" target="_blank">gclayton@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 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>
</span>Glad you figured this out, I was about to mention EINTR and handling those correctly.<br>
<span class=""><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>
</span>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>
<span class="im HOEnZb">><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>
</span><div class="HOEnZb"><div class="h5">> _______________________________________________<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>