One more fix: % svn commit source/Target/Process.cpp Sending source/Target/Process.cpp Transmitting file data . Committed revision 230066.
This ensures if you ask the process for its state, that it will respond with eStateStopped. > On Feb 20, 2015, at 1:02 PM, Greg Clayton <gclay...@apple.com> wrote: > > Fixed with: > > % svn commit source/Target/Process.cpp > Sending source/Target/Process.cpp > Transmitting file data . > Committed revision 230060. > > Please download the top of tree sources, build the Release build and make > sure it works for you. Thanks of the info so that we could track down and fix > this issue. > > Greg Clayton > >> On Feb 20, 2015, at 12:53 PM, Greg Clayton <gclay...@apple.com> wrote: >> >> I found the race condition. Seems Process::LoadCore() doesn't ensure the >> target is stopped before it returns: >> >> >> Crashed Thread: 7 >> >> Exception Type: EXC_BAD_ACCESS (SIGSEGV) >> Exception Codes: EXC_I386_GPFLT >> >> Thread 0:: Dispatch queue: com.apple.main-thread >> 0 _lldb.so 0x000000010df4d161 >> std::__1::weak_ptr<lldb_private::Process>::lock() const + 1 >> 1 _lldb.so 0x000000010fcc1d63 >> lldb_private::UnwindLLDB::DoGetFrameInfoAtIndex(unsigned int, unsigned long >> long&, unsigned long long&) + 75 >> 2 _lldb.so 0x000000010fd88c8b >> lldb_private::Unwind::GetFrameInfoAtIndex(unsigned int, unsigned long long&, >> unsigned long long&) + 61 >> 3 _lldb.so 0x000000010fd87766 >> lldb_private::StackFrameList::GetFramesUpTo(unsigned int) + 286 >> 4 _lldb.so 0x000000010fd882c1 >> lldb_private::StackFrameList::GetFrameAtIndex(unsigned int) + 185 >> 5 _lldb.so 0x000000010fd63060 >> lldb_private::Thread::GetSelectedFrame() + 48 >> 6 _lldb.so 0x000000010df4008b >> lldb::SBThread::GetSelectedFrame() + 203 >> 7 _lldb.so 0x000000010dff19e5 >> _wrap_SBThread_GetSelectedFrame(_object*, _object*) + 128 >> 8 org.python.python 0x000000010ce7c7c9 PyEval_EvalFrameEx + >> 14387 >> 9 org.python.python 0x000000010ce7f60e 0x10cdf5000 + 566798 >> 10 org.python.python 0x000000010ce7c3e3 PyEval_EvalFrameEx + >> 13389 >> 11 org.python.python 0x000000010ce7f60e 0x10cdf5000 + 566798 >> 12 org.python.python 0x000000010ce7c3e3 PyEval_EvalFrameEx + >> 13389 >> 13 org.python.python 0x000000010ce7f60e 0x10cdf5000 + 566798 >> 14 org.python.python 0x000000010ce7c3e3 PyEval_EvalFrameEx + >> 13389 >> 15 org.python.python 0x000000010ce78d62 PyEval_EvalCodeEx + >> 1413 >> 16 org.python.python 0x000000010ce787d7 PyEval_EvalCode + 54 >> 17 org.python.python 0x000000010ce987bd 0x10cdf5000 + 669629 >> 18 org.python.python 0x000000010ce98860 PyRun_FileExFlags + >> 133 >> 19 org.python.python 0x000000010ce983fd >> PyRun_SimpleFileExFlags + 769 >> 20 org.python.python 0x000000010cea9b23 Py_Main + 3051 >> 21 libdyld.dylib 0x00007fff87fa25c9 start + 1 >> >> Thread 7 Crashed: >> 0 _lldb.so 0x000000010df4d17c >> std::__1::weak_ptr<lldb_private::Process>::lock() const + 28 >> 1 _lldb.so 0x000000010fcc1d63 >> lldb_private::UnwindLLDB::DoGetFrameInfoAtIndex(unsigned int, unsigned long >> long&, unsigned long long&) + 75 >> 2 _lldb.so 0x000000010fd88c8b >> lldb_private::Unwind::GetFrameInfoAtIndex(unsigned int, unsigned long long&, >> unsigned long long&) + 61 >> 3 _lldb.so 0x000000010fd8795e >> lldb_private::StackFrameList::GetFramesUpTo(unsigned int) + 790 >> 4 _lldb.so 0x000000010fd87246 >> lldb_private::StackFrameList::ResetCurrentInlinedDepth() + 46 >> 5 _lldb.so 0x000000010fda1bcf >> lldb_private::Thread::ShouldStop(lldb_private::Event*) + 719 >> 6 _lldb.so 0x000000010fda7790 >> lldb_private::ThreadList::ShouldStop(lldb_private::Event*) + 488 >> 7 _lldb.so 0x000000010fd77f19 >> lldb_private::Process::ShouldBroadcastEvent(lldb_private::Event*) + 379 >> 8 _lldb.so 0x000000010fd754c5 >> lldb_private::Process::HandlePrivateEvent(std::__1::shared_ptr<lldb_private::Event>&) >> + 365 >> 9 _lldb.so 0x000000010fd7865b >> lldb_private::Process::RunPrivateStateThread() + 511 >> 10 _lldb.so 0x000000010fd7810f >> lldb_private::Process::PrivateStateThread(void*) + 9 >> 11 libsystem_pthread.dylib 0x00007fff81357268 _pthread_body + 131 >> 12 libsystem_pthread.dylib 0x00007fff813571e5 _pthread_start + 176 >> 13 libsystem_pthread.dylib 0x00007fff8135541d thread_start + 13 >> >> Thread 7 crashed with X86 Thread State (64-bit): >> rax: 0x0000000000000001 rbx: 0x000000012a2ce798 rcx: 0x0000000000000000 >> rdx: 0x0000000000000000 >> rdi: 0x000000012a2ce798 rsi: 0x10000000000000f0 rbp: 0x000000012a2ce780 >> rsp: 0x000000012a2ce770 >> r8: 0x0000000000000000 r9: 0x000000012a2cf000 r10: 0x00007f8fca82f400 >> r11: 0x00007f8fca82fdd0 >> r12: 0x0000000000000000 r13: 0x00007f8fc951b9a0 r14: 0x10000000000000f0 >> r15: 0x000000012a2cea10 >> rip: 0x000000010df4d17c rfl: 0x0000000000010206 cr2: 0x000000010fea75f8 >> >> >> The issue is we have a read/write lock that controls when stuff can be done >> to a process. Multiple threads can request that the run lock stay stopped, >> and only one can request that it runs. So the problem is we call >> lldb::SBThread::GetSelectedFrame() on the main thread while the private >> state thread is still finding out that the process has stopped. >> lldb::SBThread::GetSelectedFrame() tries to get the run lock and keep the >> process stopped, and it succeeds because LoadCore wasn't synchronously >> making sure the core file was ready to be played with. >> >> So the solution is to make sure that SBTarget::LoadCore() is a synchronous >> call that has the target stopped _before_ it returns. Then the process will >> be setup and ready to allow requests. >> >> A work around for now is to call time.sleep(1) after calling LoadCore() to >> give the Process::PrivateStateThread() time to get settled. Other race >> conditions could cause the run lock to no be acquired: >> >> lldb::SBFrame >> SBThread::GetSelectedFrame () >> { >> Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); >> >> SBFrame sb_frame; >> StackFrameSP frame_sp; >> Mutex::Locker api_locker; >> ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); >> >> if (exe_ctx.HasThreadScope()) >> { >> Process::StopLocker stop_locker; >> if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) >> { >> } >> else >> { >> if (log) >> log->Printf ("SBThread(%p)::GetSelectedFrame() => error: >> process is running", >> static_cast<void*>(exe_ctx.GetThreadPtr())); >> } >> >> And an error would be returned and an empty SBFrame would be returned. >> >> I'll have a fix committed shortly. >> >> Greg >> >> >>> On Feb 20, 2015, at 11:18 AM, Paul Smith <p...@mad-scientist.net> wrote: >>> >>> #!/usr/bin/env python >>> >>> import lldb >>> import sys >>> >>> def load_core(debugger, exe, core): >>> """ >>> >>> @param exe: Path to the executable binary >>> @param core: Path to the core >>> @rtype: SBProcess >>> @return: >>> """ >>> target = debugger.CreateTargetWithFileAndArch(exe, lldb.LLDB_ARCH_DEFAULT) >>> """ @type : SBTarget """ >>> if target: >>> process = target.LoadCore(core) >>> """ @type : SBProcess """ >>> if process: >>> return process >>> >>> raise Exception("Could not load core") >>> raise Exception("Could not create target") >>> >>> >>> def print_version(process): >>> """ >>> @type process: SBProcess >>> """ >>> thread = process.GetSelectedThread() >>> """ @type : SBThread """ >>> if thread: >>> frame = thread.GetSelectedFrame() >>> """ @type : SBFrame """ >>> if frame: >>> version = frame.EvaluateExpression('globals->version.data') >>> """ @type : SBValue """ >>> if version: >>> err = lldb.SBError() >>> version_string = >>> process.ReadCStringFromMemory(int(version.GetValue(), 16), 512, err) >>> if err.Success(): >>> print("*** Version: " + version_string) >>> else: >>> print("*** Error extracting version") >>> print("") >>> return >>> >>> raise Exception("Invalid expression result, can't extract version") >>> raise Exception("Invalid frame, can't extract version") >>> raise Exception("Invalid thread, can't extract version") >>> >>> >>> def print_all_backtraces(process): >>> """ >>> @type process: SBProcess >>> """ >>> print("*** All Threads Backtrace:") >>> for thread in reversed(process.threads): >>> if thread: >>> print_backtrace(thread) >>> else: >>> print("ERROR: Failed to print backtrace for a thread") >>> >>> >>> def print_backtrace(thread, include_label=False): >>> """ >>> @type thread: SBThread >>> """ >>> if include_label: >>> print("*** Backtrace:") >>> >>> print("Thread %d (core thread %d):" % (thread.GetIndexID(), >>> thread.GetThreadID())) >>> for frame in thread: >>> if frame: >>> print(frame) >>> else: >>> print("ERROR: Failed to print a frame") >>> >>> print("") >>> >>> >>> def print_environment(process): >>> """ >>> @type process: SBProcess >>> """ >>> print("*** Environment:") >>> print(' ' + '\n '.join(read_null_term_array(process, >>> 'globals->environment->envp'))) >>> print("") >>> >>> >>> def read_null_term_array(process, expr, max_length=1000): >>> """ >>> @type process: SBProcess >>> """ >>> thread = process.GetSelectedThread() >>> """ @type : SBThread """ >>> if thread: >>> frame = thread.GetSelectedFrame() >>> """ @type : SBFrame """ >>> if frame: >>> array_value = frame.EvaluateExpression(expr) >>> """ @type : SBValue """ >>> if array_value: >>> array_address = array_value.GetValueAsUnsigned() >>> idx = 0 >>> ptr_err = lldb.SBError() >>> array_data = [] >>> for i in xrange(0, max_length): >>> element_ptr = process.ReadPointerFromMemory(array_address >>> + idx * array_value.GetByteSize(), >>> ptr_err) >>> if ptr_err.Success(): >>> if element_ptr == 0: >>> break >>> >>> val_err = lldb.SBError() >>> element = process.ReadCStringFromMemory(element_ptr, >>> 1024*10, val_err) >>> if val_err.Success(): >>> array_data.append(element) >>> else: >>> print("ERROR: Unable to read value at address %s" >>> % (str(element_ptr))) >>> >>> idx += 1 >>> else: >>> print("ERROR: Unable to read pointer at address %s" % >>> (str(array_address + idx * >>> array_value.GetByteSize()),)) >>> break >>> >>> return array_data >>> >>> raise Exception("Unable to read array address for %s" % (expr,)) >>> raise Exception("Invalid frame for %s" % (expr,)) >>> raise Exception("Invalid thread for %s" % (expr,)) >>> >>> >>> def main(): >>> if len(sys.argv) != 3: >>> print("usage: python %s core_file exe_file" % (sys.argv[0],)) >>> exit(1) >>> >>> core = sys.argv[1] >>> exe = sys.argv[2] >>> >>> debugger = lldb.SBDebugger.Create() >>> """ @type : SBDebugger """ >>> >>> process = load_core(debugger, exe, core) >>> if process: >>> print_version(process) >>> print_backtrace(process.GetSelectedThread(), True) >>> print_all_backtraces(process) >>> print_environment(process) >>> else: >>> print("Failed to debug core " + core) >>> >>> if __name__ == '__main__': >>> main() >> >> >> _______________________________________________ >> lldb-dev mailing list >> lldb-dev@cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev > > > _______________________________________________ > lldb-dev mailing list > lldb-dev@cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev _______________________________________________ lldb-dev mailing list lldb-dev@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev