[lldb-dev] Why is storing SBTarget in a private field causing random crash?

Greg Clayton via lldb-dev lldb-dev at lists.llvm.org
Fri Feb 12 09:50:29 PST 2016


This is a clear bug in LLDB. If you have a repro case, please file a bug and attach the instructions on how to make this happen. Our API must be able to handle things like this.

SBTarget has a shared pointer to a lldb_private::Target. If you have a reference to a target, it should keep that target alive and it shouldn't crash later when it is actually freed. 

So please file a bug and we'll get it fixed. For a work around for now, yes, setting all SB references to None should help you work around the issue.

Greg

> On Feb 7, 2016, at 10:41 PM, Jeffrey Tan via lldb-dev <lldb-dev at lists.llvm.org> wrote:
> 
> Hi,
> 
> 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). 
> 
> In the code, if I modify the two "self.target" to local variable "target" the random crash will disappear. 
> 
> 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()?
> 
> 
> ==========================Crash Stack==========================
> Crashed Thread:        0  Dispatch queue: com.apple.main-thread
> 
> Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
> Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000010
> 
> VM Regions Near 0x10:
> --> 
>     __TEXT                 000000010d145000-000000010d146000 [    4K] r-x/rwx SM=COW  /System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
> 
> Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
> 0   com.apple.LLDB.framework      	0x00000001101c037d lldb_private::Listener::BroadcasterWillDestruct(lldb_private::Broadcaster*) + 95
> 1   com.apple.LLDB.framework      	0x00000001101a0da2 lldb_private::Broadcaster::Clear() + 50
> 2   com.apple.LLDB.framework      	0x00000001101a0ced lldb_private::Broadcaster::~Broadcaster() + 75
> 3   com.apple.LLDB.framework      	0x00000001103d6879 lldb_private::Target::~Target() + 741
> 4   com.apple.LLDB.framework      	0x00000001103d6c20 lldb_private::Target::~Target() + 14
> 5   libc++.1.dylib                	0x00007fff896448a6 std::__1::__shared_weak_count::__release_shared() + 44
> 6   com.apple.LLDB.framework      	0x000000010e560664 _wrap_delete_SBTarget(_object*, _object*) + 123
> 7   org.python.python             	0x000000010d15a50a PyObject_Call + 99
> 
> 
> ==========================Code==========================
> from find_lldb import lldb
> from simplest_event_thread import LLDBListenerThread
> import unittest
> import threading
> 
> running_signal = threading.Event()
> stopped_signal = threading.Event()
> 
> def launch_debugging(debugger, stop_at_entry):
>     error = lldb.SBError()
>     listener = lldb.SBListener('Chrome Dev Tools Listener')
>     target = debugger.GetSelectedTarget()
>     process = target.Launch (listener,
>                     None,      # argv
>                     None,      # envp
>                     None,      # stdin_path
>                     None,      # stdout_path
>                     None,      # stderr_path
>                     None,      # working directory
>                     0,         # launch flags
>                     stop_at_entry,      # Stop at entry
>                     error)     # error
>     print 'Launch result: %s' % str(error)
> 
>     event_thread = LLDBListenerThread(debugger, running_signal, stopped_signal)
>     event_thread.start()
> 
>     running_signal.set()
>     return event_thread
> 
> class DebuggerTestCase:
> 
>     def wait_for_process_stop(self):
>         running_signal.wait()
>         running_signal.clear()
>         stopped_signal.wait()
>         stopped_signal.clear()
> 
>     def test_breakpoint_at_line(self):
>         debugger = lldb.SBDebugger.Create()
>         debugger.SetAsync(True)
>         executable_path = '~/Personal/compiler/CompilerConstruction/code/compiler'
>         self.target = debugger.CreateTargetWithFileAndArch(executable_path, lldb.LLDB_ARCH_DEFAULT)
> 
>         event_thread = launch_debugging(debugger, stop_at_entry=True)
> 
>         process = debugger.GetSelectedTarget().process
>         self.wait_for_process_stop() # wait for entry breakpoint.
>         self.target.BreakpointCreateByName('main')
>         process.Continue()
>         self.wait_for_process_stop() # wait for main breakpoint.
> 
>         event_thread.should_quit = True
>         event_thread.join()
>         lldb.SBDebugger.Destroy(debugger)
> 
> if __name__ == '__main__':
>     test = DebuggerTestCase()
>     for i in range(20):
>         test.test_breakpoint_at_line()
> _______________________________________________
> lldb-dev mailing list
> lldb-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev



More information about the lldb-dev mailing list