[lldb-dev] Race condition or wrong API usage?

Filipe Cabecinhas filcab at gmail.com
Tue May 8 10:59:15 PDT 2012


Hi again, 

It seems that, if I use the debugger's listener (like Driver.cpp does), it works:

If I change the test to do this:
        listener = self.dbg.GetListener()
instead of:
listener = lldb.SBListener("test-listener")


Everything works (after we take into account the additional events related to the program's STDOUT). But shouldn't my first version work? I setup the SBListener before doing anything that will use it, and the events should be propagated to every listener that is hanging to the Process broadcaster. Or am I missing something?

Thanks,

  Filipe


On Tuesday, May 8, 2012 at 12:02 PM, Filipe Cabecinhas wrote:

> Hi all! 
> 
> I'm having some weird problems with asynchronous API usage. I will address it in this email as if it was a bug, but it may be wrong API usage from my part.
> 
> The main problem is the run lock being write locked when the process is stopped (and I got a state changed event).
> What happens is:
> 
> Create a target (a simple 'hello world'-like program) and set a breakpoint
> Set Async mode.
> 
> Set up an SBListener that will listen (on the SBDebugger) for lldb.SBProcess.eBroadcastBitStateChanged, from event class lldb.SBProcess.GetBroadcasterClassName().
> Call SBTarget::LaunchSimple(None, None, os.getcwd())
> Wait for an event
> The process is now in a stopped state (checked using GetStateFromEvent() == eStateStopped)
> Try to get the stopped thread. There isn't any (the only thread has eStopReasonInvalid).
> 
> Why does this happen?
> 
> SBTarget::Launch() will start the process (the run_lock gets created write-locked, the Process' public state will be eStateRunning) and wait for it to stop (when it stops, the Event's DoOnRemoval will change the public state (to eStateStopped) of the Process and call WriteUnlock()).
> After the process stopped on entry, we want to continue until we hit our breakpoint. SBTarget::Launch calls Process::Resume, which will call WriteTryLock (succeeding) and call into Process::PrivateResume()
> 
> The lock will not be unlocked again.
> The Process' private state will toggle between the stopped and running states several times, before stopping at the breakpoint. When it stops at the breakpoint, it will set the Process' public state to eStateStopped. But the public state was already eStateStopped, so we won't call WriteUnlock on Process.cpp:1310.
> 
> Any clues on where to look for? I've started debugging it but maybe Greg will know best where to look and how to fix this.
> 
> Attached is a test that show the problem (main.cpp is from python_api/process).
> 
> Thanks, 
> 
> Filipe 
> 
> 
> Attachments: 
> - main.cpp
> 
> - Makefile
> 
> - TestProcessRWLock.py
> 






More information about the lldb-dev mailing list