blob: 28912a66897201da47c6fbdf73b46755d65603cd [file] [log] [blame]
Johnny Chen1605cf62010-09-08 22:54:46 +00001"""
Johnny Chenb51d87d2010-10-07 21:38:28 +00002This LLDB module contains miscellaneous utilities.
Johnny Chen1605cf62010-09-08 22:54:46 +00003"""
4
5import lldb
Johnny Chen30425e92010-10-07 18:52:48 +00006import sys
Johnny Chened5f04e2010-10-15 23:33:18 +00007import StringIO
Johnny Chen1605cf62010-09-08 22:54:46 +00008
Johnny Chen168a61a2010-10-22 21:31:03 +00009# ===========================================
10# Iterator for lldb aggregate data structures
11# ===========================================
Johnny Chen84a6d6f2010-10-15 01:18:29 +000012
Johnny Chen4d72c742010-10-10 20:25:10 +000013def lldb_iter(obj, getsize, getelem):
Johnny Chen164bf882010-10-09 01:31:09 +000014 """
15 A generator adaptor for lldb aggregate data structures.
16
Johnny Chen4d72c742010-10-10 20:25:10 +000017 API clients pass in the aggregate object, the name of the method to get the
18 size of the object, and the name of the method to get the element given an
19 index.
Johnny Chen164bf882010-10-09 01:31:09 +000020
21 Example usage:
22
23 def disassemble_instructions (insts):
Johnny Chen4d72c742010-10-10 20:25:10 +000024 from lldbutil import lldb_iter
25 for i in lldb_iter(insts, 'GetSize', 'GetInstructionAtIndex'):
Johnny Chen164bf882010-10-09 01:31:09 +000026 print i
27 """
Johnny Chen4d72c742010-10-10 20:25:10 +000028 size = getattr(obj, getsize)
29 elem = getattr(obj, getelem)
30 for i in range(size()):
31 yield elem(i)
Johnny Chen164bf882010-10-09 01:31:09 +000032
33
Johnny Chen168a61a2010-10-22 21:31:03 +000034# =================================================
35# Convert some enum value to its string counterpart
36# =================================================
Johnny Chenbe683bc2010-10-07 22:15:58 +000037
38def StateTypeString(enum):
39 """Returns the stateType string given an enum."""
40 if enum == lldb.eStateInvalid:
Johnny Chen59b84772010-10-18 15:46:54 +000041 return "invalid"
Johnny Chenbe683bc2010-10-07 22:15:58 +000042 elif enum == lldb.eStateUnloaded:
Johnny Chen59b84772010-10-18 15:46:54 +000043 return "unloaded"
Johnny Chenbe683bc2010-10-07 22:15:58 +000044 elif enum == lldb.eStateAttaching:
Johnny Chen59b84772010-10-18 15:46:54 +000045 return "attaching"
Johnny Chenbe683bc2010-10-07 22:15:58 +000046 elif enum == lldb.eStateLaunching:
Johnny Chen59b84772010-10-18 15:46:54 +000047 return "launching"
Johnny Chenbe683bc2010-10-07 22:15:58 +000048 elif enum == lldb.eStateStopped:
Johnny Chen59b84772010-10-18 15:46:54 +000049 return "stopped"
Johnny Chenbe683bc2010-10-07 22:15:58 +000050 elif enum == lldb.eStateRunning:
Johnny Chen59b84772010-10-18 15:46:54 +000051 return "running"
Johnny Chenbe683bc2010-10-07 22:15:58 +000052 elif enum == lldb.eStateStepping:
Johnny Chen59b84772010-10-18 15:46:54 +000053 return "stepping"
Johnny Chenbe683bc2010-10-07 22:15:58 +000054 elif enum == lldb.eStateCrashed:
Johnny Chen59b84772010-10-18 15:46:54 +000055 return "crashed"
Johnny Chenbe683bc2010-10-07 22:15:58 +000056 elif enum == lldb.eStateDetached:
Johnny Chen59b84772010-10-18 15:46:54 +000057 return "detached"
Johnny Chenbe683bc2010-10-07 22:15:58 +000058 elif enum == lldb.eStateExited:
Johnny Chen59b84772010-10-18 15:46:54 +000059 return "exited"
Johnny Chenbe683bc2010-10-07 22:15:58 +000060 elif enum == lldb.eStateSuspended:
Johnny Chen59b84772010-10-18 15:46:54 +000061 return "suspended"
Johnny Chenbe683bc2010-10-07 22:15:58 +000062 else:
63 raise Exception("Unknown stopReason enum")
64
65def StopReasonString(enum):
66 """Returns the stopReason string given an enum."""
67 if enum == lldb.eStopReasonInvalid:
Johnny Chen59b84772010-10-18 15:46:54 +000068 return "invalid"
Johnny Chenbe683bc2010-10-07 22:15:58 +000069 elif enum == lldb.eStopReasonNone:
Johnny Chen59b84772010-10-18 15:46:54 +000070 return "none"
Johnny Chenbe683bc2010-10-07 22:15:58 +000071 elif enum == lldb.eStopReasonTrace:
Johnny Chen59b84772010-10-18 15:46:54 +000072 return "trace"
Johnny Chenbe683bc2010-10-07 22:15:58 +000073 elif enum == lldb.eStopReasonBreakpoint:
Johnny Chen59b84772010-10-18 15:46:54 +000074 return "breakpoint"
Johnny Chenbe683bc2010-10-07 22:15:58 +000075 elif enum == lldb.eStopReasonWatchpoint:
Johnny Chen59b84772010-10-18 15:46:54 +000076 return "watchpoint"
Johnny Chenbe683bc2010-10-07 22:15:58 +000077 elif enum == lldb.eStopReasonSignal:
Johnny Chen59b84772010-10-18 15:46:54 +000078 return "signal"
Johnny Chenbe683bc2010-10-07 22:15:58 +000079 elif enum == lldb.eStopReasonException:
Johnny Chen59b84772010-10-18 15:46:54 +000080 return "exception"
Johnny Chenbe683bc2010-10-07 22:15:58 +000081 elif enum == lldb.eStopReasonPlanComplete:
Johnny Chen59b84772010-10-18 15:46:54 +000082 return "plancomplete"
Johnny Chenbe683bc2010-10-07 22:15:58 +000083 else:
84 raise Exception("Unknown stopReason enum")
85
86
Johnny Chen168a61a2010-10-22 21:31:03 +000087# ==================================================
88# Utility functions related to Threads and Processes
89# ==================================================
Johnny Chenbe683bc2010-10-07 22:15:58 +000090
Johnny Chen1605cf62010-09-08 22:54:46 +000091def GetFunctionNames(thread):
92 """
93 Returns a sequence of function names from the stack frames of this thread.
94 """
95 def GetFuncName(i):
96 return thread.GetFrameAtIndex(i).GetFunction().GetName()
97
98 return map(GetFuncName, range(thread.GetNumFrames()))
99
100
Johnny Chenb51d87d2010-10-07 21:38:28 +0000101def GetSymbolNames(thread):
102 """
103 Returns a sequence of symbols for this thread.
104 """
105 def GetSymbol(i):
106 return thread.GetFrameAtIndex(i).GetSymbol().GetName()
107
108 return map(GetSymbol, range(thread.GetNumFrames()))
109
110
111def GetPCAddresses(thread):
112 """
113 Returns a sequence of pc addresses for this thread.
114 """
115 def GetPCAddress(i):
116 return thread.GetFrameAtIndex(i).GetPCAddress()
117
118 return map(GetPCAddress, range(thread.GetNumFrames()))
119
120
Johnny Chen1605cf62010-09-08 22:54:46 +0000121def GetFilenames(thread):
122 """
123 Returns a sequence of file names from the stack frames of this thread.
124 """
125 def GetFilename(i):
126 return thread.GetFrameAtIndex(i).GetLineEntry().GetFileSpec().GetFilename()
127
128 return map(GetFilename, range(thread.GetNumFrames()))
129
130
131def GetLineNumbers(thread):
132 """
133 Returns a sequence of line numbers from the stack frames of this thread.
134 """
135 def GetLineNumber(i):
136 return thread.GetFrameAtIndex(i).GetLineEntry().GetLine()
137
138 return map(GetLineNumber, range(thread.GetNumFrames()))
139
140
141def GetModuleNames(thread):
142 """
143 Returns a sequence of module names from the stack frames of this thread.
144 """
145 def GetModuleName(i):
146 return thread.GetFrameAtIndex(i).GetModule().GetFileSpec().GetFilename()
147
148 return map(GetModuleName, range(thread.GetNumFrames()))
149
150
Johnny Chen88866ac2010-09-09 00:55:07 +0000151def GetStackFrames(thread):
152 """
153 Returns a sequence of stack frames for this thread.
154 """
155 def GetStackFrame(i):
156 return thread.GetFrameAtIndex(i)
157
158 return map(GetStackFrame, range(thread.GetNumFrames()))
159
160
Johnny Chen30425e92010-10-07 18:52:48 +0000161def PrintStackTrace(thread, string_buffer = False):
Johnny Chen1605cf62010-09-08 22:54:46 +0000162 """Prints a simple stack trace of this thread."""
Johnny Chen30425e92010-10-07 18:52:48 +0000163
Johnny Chened5f04e2010-10-15 23:33:18 +0000164 output = StringIO.StringIO() if string_buffer else sys.stdout
Johnny Chenb51d87d2010-10-07 21:38:28 +0000165 target = thread.GetProcess().GetTarget()
166
Johnny Chen1605cf62010-09-08 22:54:46 +0000167 depth = thread.GetNumFrames()
168
169 mods = GetModuleNames(thread)
170 funcs = GetFunctionNames(thread)
Johnny Chenb51d87d2010-10-07 21:38:28 +0000171 symbols = GetSymbolNames(thread)
Johnny Chen1605cf62010-09-08 22:54:46 +0000172 files = GetFilenames(thread)
173 lines = GetLineNumbers(thread)
Johnny Chenb51d87d2010-10-07 21:38:28 +0000174 addrs = GetPCAddresses(thread)
Johnny Chen30425e92010-10-07 18:52:48 +0000175
176 print >> output, "Stack trace for thread id={0:#x} name={1} queue={2}:".format(
Johnny Chen1605cf62010-09-08 22:54:46 +0000177 thread.GetThreadID(), thread.GetName(), thread.GetQueueName())
178
Johnny Chenb51d87d2010-10-07 21:38:28 +0000179 for i in range(depth):
180 frame = thread.GetFrameAtIndex(i)
181 function = frame.GetFunction()
Johnny Chen1605cf62010-09-08 22:54:46 +0000182
Johnny Chenb51d87d2010-10-07 21:38:28 +0000183 load_addr = addrs[i].GetLoadAddress(target)
184 if not function.IsValid():
185 file_addr = addrs[i].GetFileAddress()
186 print >> output, " frame #{num}: {addr:#016x} {mod}`{symbol} + ????".format(
187 num=i, addr=load_addr, mod=mods[i], symbol=symbols[i])
188 else:
189 print >> output, " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line}".format(
190 num=i, addr=load_addr, mod=mods[i], func=funcs[i], file=files[i], line=lines[i])
191
192 if string_buffer:
Johnny Chened5f04e2010-10-15 23:33:18 +0000193 return output.getvalue()
Johnny Chenb51d87d2010-10-07 21:38:28 +0000194
195
196def PrintStackTraces(process, string_buffer = False):
197 """Prints the stack traces of all the threads."""
198
Johnny Chened5f04e2010-10-15 23:33:18 +0000199 output = StringIO.StringIO() if string_buffer else sys.stdout
Johnny Chenb51d87d2010-10-07 21:38:28 +0000200
201 print >> output, "Stack traces for " + repr(process)
202
203 for i in range(process.GetNumThreads()):
204 print >> output, PrintStackTrace(process.GetThreadAtIndex(i), string_buffer=True)
Johnny Chen30425e92010-10-07 18:52:48 +0000205
206 if string_buffer:
Johnny Chened5f04e2010-10-15 23:33:18 +0000207 return output.getvalue()