monobt.py 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. import lldb
  2. def print_frames(thread, num_frames, current_thread):
  3. # TODO: Make output header similar to bt.
  4. print '%c thread #%i' % ('*' if current_thread else ' ', thread.idx)
  5. if current_thread:
  6. selected_frame = thread.GetSelectedFrame()
  7. for frame in thread.frames[:+num_frames]:
  8. pc = str(frame.addr)
  9. fmt = ' %c %s'
  10. var = frame
  11. if pc[0] == '0':
  12. try:
  13. framestr = frame.EvaluateExpression('(char*)mono_pmip((void*)%s)' % pc).summary[1:-1]
  14. var = 'frame #%i: %s%s' % (frame.idx, pc, framestr)
  15. except:
  16. pass
  17. print fmt % ('*' if current_thread and frame.idx == selected_frame.idx else ' ', var)
  18. def monobt(debugger, command, result, dict):
  19. opts = {'all_bt': False, 'num_frames': None}
  20. if command == 'all':
  21. opts['all_bt'] = True
  22. elif command.isdigit():
  23. opts['num_frames'] = int(command)
  24. elif command != '':
  25. print 'error: monobt [<number>|all]'
  26. return
  27. target = debugger.GetSelectedTarget()
  28. process = target.process
  29. if not process.IsValid():
  30. print 'error: invalid process'
  31. return
  32. if opts['all_bt']:
  33. for thread in process.threads:
  34. print_frames(thread, len(thread), process.selected_thread == thread)
  35. print ''
  36. else:
  37. thread = process.selected_thread
  38. num_frames = len(thread) if opts['num_frames'] is None else opts['num_frames']
  39. print_frames(thread, num_frames, True)
  40. return None
  41. def __lldb_init_module (debugger, dict):
  42. # This initializer is being run from LLDB in the embedded command interpreter
  43. # Add any commands contained in this module to LLDB
  44. debugger.HandleCommand('command script add -f monobt.monobt monobt')
  45. print '"monobt" command installed'