Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / data / lldb / monobt.py
1 import lldb
2
3 def print_frames(thread, num_frames, current_thread):
4     # TODO: Make output header similar to bt.
5     print '%c thread #%i' % ('*' if current_thread else ' ', thread.idx)
6
7     if current_thread:
8         selected_frame = thread.GetSelectedFrame()
9
10     for frame in thread.frames[:+num_frames]:
11         pc = str(frame.addr)
12         var = frame
13         function_name = frame.GetFunctionName()
14         if function_name == "ves_exec_method_with_context":
15             try:
16                 s = 'frame->runtime_method->method'
17                 klassname = frame.EvaluateExpression('(char*) ' + s + '->klass->name').summary[1:-1]
18                 methodname = frame.EvaluateExpression('(char*) ' + s + '->name').summary[1:-1]
19
20                 ipoffset = frame.EvaluateExpression('ip').GetValueAsUnsigned()
21                 insn = ''
22                 if ipoffset != 0:
23                     ipoffset -= frame.EvaluateExpression('rtm->code').GetValueAsUnsigned()
24                     insn = "\"" + frame.EvaluateExpression('mono_interp_opname [*ip]').summary[1:-1] + "\""
25                 var = '%s::%s @ %d %s || %s' % (klassname, methodname, ipoffset, insn, frame)
26             except Exception as e:
27                 print "DBG: execfail:" + str(e)
28         elif function_name == "mono_interp_transform_method":
29             try:
30                 s = 'runtime_method->method'
31                 klassname = frame.EvaluateExpression('(char*) ' + s + '->klass->name').summary[1:-1]
32                 methodname = frame.EvaluateExpression('(char*) ' + s + '->name').summary[1:-1]
33                 var = 'transforming %s::%s || %s' % (klassname, methodname, frame)
34             except Exception as e:
35                 print "DBG: transformfail:" + str(e)
36         elif pc[0] == '0':
37             try:
38                 framestr = frame.EvaluateExpression('(char*)mono_pmip((void*)%s)' % pc).summary[1:-1]
39                 var = 'frame #%i: %s%s' % (frame.idx, pc, framestr)
40             except:
41                 pass
42
43         print '  %c %s' % ('*' if current_thread and frame.idx == selected_frame.idx else ' ', var)
44
45 def monobt(debugger, command, result, dict):
46     opts = {'all_bt': False, 'num_frames': None}
47
48     if command == 'all':
49         opts['all_bt'] = True
50     elif command.isdigit():
51         opts['num_frames'] = int(command)
52     elif command != '':
53         print 'error: monobt [<number>|all]'
54         return
55
56     target = debugger.GetSelectedTarget()
57     process = target.process
58
59     if not process.IsValid():
60         print 'error: invalid process'
61         return
62
63     if opts['all_bt']:
64         for thread in process.threads:
65             print_frames(thread, len(thread), process.selected_thread == thread)
66             print ''
67     else:
68         thread = process.selected_thread
69         num_frames = len(thread) if opts['num_frames'] is None else opts['num_frames']
70         print_frames(thread, num_frames, True)
71
72     return None
73
74 def __lldb_init_module (debugger, dict):
75     # This initializer is being run from LLDB in the embedded command interpreter
76     # Add any commands contained in this module to LLDB
77     debugger.HandleCommand('command script add -f monobt.monobt monobt')
78     debugger.HandleCommand('command alias mbt monobt')
79     print '"monobt" command installed'