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

Reply via email to