<div dir="ltr">Hi,<div><br></div><div>I have been spending long time troubleshooting a race condition in our lldb python test. I finally narrowed down to one code change that caused the race: basically, whenever I store SBTarget in DebuggerTestCase's self.target field lldb will randomly crash during destruction(see below). </div><div><br></div><div>In the code, if I modify the two "self.target" to local variable "target" the random crash will disappear. </div><div><br></div><div>I am not a python expert. Why is holding SBTarget will cause the test to random crash? Do I have to set every SBXXX fields to None before calling SBDebugger.Destroy()?</div><div><br></div><div><br></div><div>==========================Crash Stack==========================<br></div><div><div>Crashed Thread:        0  Dispatch queue: com.apple.main-thread</div><div><br></div><div>Exception Type:        EXC_BAD_ACCESS (SIGSEGV)</div><div>Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000010</div><div><br></div><div>VM Regions Near 0x10:</div><div>--> </div><div>    __TEXT                 000000010d145000-000000010d146000 [    4K] r-x/rwx SM=COW  /System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python</div><div><br></div><div>Thread 0 Crashed:: Dispatch queue: com.apple.main-thread</div><div>0   com.apple.LLDB.framework      <span class="" style="white-space:pre"> </span>0x00000001101c037d lldb_private::Listener::BroadcasterWillDestruct(lldb_private::Broadcaster*) + 95</div><div>1   com.apple.LLDB.framework      <span class="" style="white-space:pre">  </span>0x00000001101a0da2 lldb_private::Broadcaster::Clear() + 50</div><div>2   com.apple.LLDB.framework      <span class="" style="white-space:pre">   </span>0x00000001101a0ced lldb_private::Broadcaster::~Broadcaster() + 75</div><div>3   com.apple.LLDB.framework      <span class="" style="white-space:pre">    </span>0x00000001103d6879 lldb_private::Target::~Target() + 741</div><div>4   com.apple.LLDB.framework      <span class="" style="white-space:pre">     </span>0x00000001103d6c20 lldb_private::Target::~Target() + 14</div><div>5   libc++.1.dylib                <span class="" style="white-space:pre"> </span>0x00007fff896448a6 std::__1::__shared_weak_count::__release_shared() + 44</div><div>6   com.apple.LLDB.framework      <span class="" style="white-space:pre">    </span>0x000000010e560664 _wrap_delete_SBTarget(_object*, _object*) + 123</div><div>7   org.python.python             <span class="" style="white-space:pre">        </span>0x000000010d15a50a PyObject_Call + 99</div></div><div><br></div><div><br></div><div>==========================Code==========================</div><div><div>from find_lldb import lldb</div><div>from simplest_event_thread import LLDBListenerThread</div><div>import unittest</div><div>import threading</div><div><br></div><div>running_signal = threading.Event()</div><div>stopped_signal = threading.Event()</div><div><br></div><div>def launch_debugging(debugger, stop_at_entry):</div><div>    error = lldb.SBError()</div><div>    listener = lldb.SBListener('Chrome Dev Tools Listener')</div><div>    target = debugger.GetSelectedTarget()</div><div>    process = target.Launch (listener,</div><div>                    None,      # argv</div><div>                    None,      # envp</div><div>                    None,      # stdin_path</div><div>                    None,      # stdout_path</div><div>                    None,      # stderr_path</div><div>                    None,      # working directory</div><div>                    0,         # launch flags</div><div>                    stop_at_entry,      # Stop at entry</div><div>                    error)     # error</div><div>    print 'Launch result: %s' % str(error)</div><div><br></div><div>    event_thread = LLDBListenerThread(debugger, running_signal, stopped_signal)</div><div>    event_thread.start()</div><div><br></div><div>    running_signal.set()</div><div>    return event_thread</div><div><br></div><div>class DebuggerTestCase:</div><div><br></div><div>    def wait_for_process_stop(self):</div><div>        running_signal.wait()</div><div>        running_signal.clear()</div><div>        stopped_signal.wait()</div><div>        stopped_signal.clear()</div><div><br></div><div>    def test_breakpoint_at_line(self):</div><div>        debugger = lldb.SBDebugger.Create()</div><div>        debugger.SetAsync(True)</div><div>        executable_path = '~/Personal/compiler/CompilerConstruction/code/compiler'</div><div>        <b>self.target</b> = debugger.CreateTargetWithFileAndArch(executable_path, lldb.LLDB_ARCH_DEFAULT)</div><div><br></div><div>        event_thread = launch_debugging(debugger, stop_at_entry=True)</div><div><br></div><div>        process = debugger.GetSelectedTarget().process</div><div>        self.wait_for_process_stop() # wait for entry breakpoint.</div><div>        <b>self.target</b>.BreakpointCreateByName('main')</div><div>        process.Continue()</div><div>        self.wait_for_process_stop() # wait for main breakpoint.</div><div><br></div><div>        event_thread.should_quit = True</div><div>        event_thread.join()</div><div>        lldb.SBDebugger.Destroy(debugger)</div><div><br></div><div>if __name__ == '__main__':</div><div>    test = DebuggerTestCase()</div><div>    for i in range(20):</div><div>        test.test_breakpoint_at_line()</div></div></div>