468663ddbb
Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
80 lines
3.1 KiB
Python
80 lines
3.1 KiB
Python
import lldb
|
|
import traceback
|
|
|
|
def print_frames(thread, num_frames, current_thread):
|
|
# TODO: Make output header similar to bt.
|
|
print('%c thread #%i' % ('*' if current_thread else ' ', thread.idx))
|
|
|
|
if current_thread:
|
|
selected_frame = thread.GetSelectedFrame()
|
|
|
|
for frame in thread.frames[:+num_frames]:
|
|
pc = str(frame.addr)
|
|
var = frame
|
|
function_name = frame.GetFunctionName()
|
|
if function_name == "interp_exec_method_full":
|
|
try:
|
|
s = 'frame->imethod->method'
|
|
methoddesc = frame.EvaluateExpression('(char*) mono_method_full_name (' + s + ', 1)').summary[1:-1]
|
|
|
|
ipoffset = frame.EvaluateExpression('ip').GetValueAsUnsigned()
|
|
insn = ''
|
|
if ipoffset != 0:
|
|
ipoffset -= frame.EvaluateExpression('frame->imethod->code').GetValueAsUnsigned()
|
|
insn = "\"" + frame.EvaluateExpression('mono_interp_opname (*ip)').summary[1:-1] + "\""
|
|
var = '%s @ %d %s || %s' % (methoddesc, ipoffset, insn, frame)
|
|
except Exception as e:
|
|
traceback.print_exc()
|
|
elif function_name == "mono_interp_transform_method":
|
|
try:
|
|
s = 'runtime_method->method'
|
|
klassname = frame.EvaluateExpression('(char*) ' + s + '->klass->name').summary[1:-1]
|
|
methodname = frame.EvaluateExpression('(char*) ' + s + '->name').summary[1:-1]
|
|
var = 'transforming %s::%s || %s' % (klassname, methodname, frame)
|
|
except Exception as e:
|
|
print("DBG: transformfail:" + str(e))
|
|
elif pc[0] == '0':
|
|
try:
|
|
framestr = frame.EvaluateExpression('(char*)mono_pmip((void*)%s)' % pc).summary[1:-1]
|
|
var = 'frame #%i: %s%s' % (frame.idx, pc, framestr)
|
|
except:
|
|
pass
|
|
|
|
print(' %c %s' % ('*' if current_thread and frame.idx == selected_frame.idx else ' ', var))
|
|
|
|
def monobt(debugger, command, result, dict):
|
|
opts = {'all_bt': False, 'num_frames': None}
|
|
|
|
if command == 'all':
|
|
opts['all_bt'] = True
|
|
elif command.isdigit():
|
|
opts['num_frames'] = int(command)
|
|
elif command != '':
|
|
print('error: monobt [<number>|all]')
|
|
return
|
|
|
|
target = debugger.GetSelectedTarget()
|
|
process = target.process
|
|
|
|
if not process.IsValid():
|
|
print('error: invalid process')
|
|
return
|
|
|
|
if opts['all_bt']:
|
|
for thread in process.threads:
|
|
print_frames(thread, len(thread), process.selected_thread == thread)
|
|
print('')
|
|
else:
|
|
thread = process.selected_thread
|
|
num_frames = len(thread) if opts['num_frames'] is None else opts['num_frames']
|
|
print_frames(thread, num_frames, True)
|
|
|
|
return None
|
|
|
|
def __lldb_init_module (debugger, dict):
|
|
# This initializer is being run from LLDB in the embedded command interpreter
|
|
# Add any commands contained in this module to LLDB
|
|
debugger.HandleCommand('command script add -f monobt.monobt monobt')
|
|
debugger.HandleCommand('command alias mbt monobt')
|
|
print('"monobt" command installed')
|