blob: b4a6e40bdcab64457f777cca17f52f3cbfd1d73a [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
Johnny Chen2c8d1592010-11-03 21:37:58 +000086def ValueTypeString(enum):
87 """Returns the valueType string given an enum."""
88 if enum == lldb.eValueTypeInvalid:
89 return "invalid"
90 elif enum == lldb.eValueTypeVariableGlobal:
91 return "global_variable"
92 elif enum == lldb.eValueTypeVariableStatic:
93 return "static_variable"
94 elif enum == lldb.eValueTypeVariableArgument:
95 return "argument_variable"
96 elif enum == lldb.eValueTypeVariableLocal:
97 return "local_variable"
98 elif enum == lldb.eValueTypeRegister:
99 return "register"
100 elif enum == lldb.eValueTypeRegisterSet:
101 return "register_set"
102 elif enum == lldb.eValueTypeConstResult:
103 return "constant_result"
104 else:
105 raise Exception("Unknown valueType enum")
106
Johnny Chenbe683bc2010-10-07 22:15:58 +0000107
Johnny Chen168a61a2010-10-22 21:31:03 +0000108# ==================================================
109# Utility functions related to Threads and Processes
110# ==================================================
Johnny Chenbe683bc2010-10-07 22:15:58 +0000111
Johnny Chen1605cf62010-09-08 22:54:46 +0000112def GetFunctionNames(thread):
113 """
114 Returns a sequence of function names from the stack frames of this thread.
115 """
116 def GetFuncName(i):
117 return thread.GetFrameAtIndex(i).GetFunction().GetName()
118
119 return map(GetFuncName, range(thread.GetNumFrames()))
120
121
Johnny Chenb51d87d2010-10-07 21:38:28 +0000122def GetSymbolNames(thread):
123 """
124 Returns a sequence of symbols for this thread.
125 """
126 def GetSymbol(i):
127 return thread.GetFrameAtIndex(i).GetSymbol().GetName()
128
129 return map(GetSymbol, range(thread.GetNumFrames()))
130
131
132def GetPCAddresses(thread):
133 """
134 Returns a sequence of pc addresses for this thread.
135 """
136 def GetPCAddress(i):
137 return thread.GetFrameAtIndex(i).GetPCAddress()
138
139 return map(GetPCAddress, range(thread.GetNumFrames()))
140
141
Johnny Chen1605cf62010-09-08 22:54:46 +0000142def GetFilenames(thread):
143 """
144 Returns a sequence of file names from the stack frames of this thread.
145 """
146 def GetFilename(i):
147 return thread.GetFrameAtIndex(i).GetLineEntry().GetFileSpec().GetFilename()
148
149 return map(GetFilename, range(thread.GetNumFrames()))
150
151
152def GetLineNumbers(thread):
153 """
154 Returns a sequence of line numbers from the stack frames of this thread.
155 """
156 def GetLineNumber(i):
157 return thread.GetFrameAtIndex(i).GetLineEntry().GetLine()
158
159 return map(GetLineNumber, range(thread.GetNumFrames()))
160
161
162def GetModuleNames(thread):
163 """
164 Returns a sequence of module names from the stack frames of this thread.
165 """
166 def GetModuleName(i):
167 return thread.GetFrameAtIndex(i).GetModule().GetFileSpec().GetFilename()
168
169 return map(GetModuleName, range(thread.GetNumFrames()))
170
171
Johnny Chen88866ac2010-09-09 00:55:07 +0000172def GetStackFrames(thread):
173 """
174 Returns a sequence of stack frames for this thread.
175 """
176 def GetStackFrame(i):
177 return thread.GetFrameAtIndex(i)
178
179 return map(GetStackFrame, range(thread.GetNumFrames()))
180
181
Johnny Chen30425e92010-10-07 18:52:48 +0000182def PrintStackTrace(thread, string_buffer = False):
Johnny Chen1605cf62010-09-08 22:54:46 +0000183 """Prints a simple stack trace of this thread."""
Johnny Chen30425e92010-10-07 18:52:48 +0000184
Johnny Chened5f04e2010-10-15 23:33:18 +0000185 output = StringIO.StringIO() if string_buffer else sys.stdout
Johnny Chenb51d87d2010-10-07 21:38:28 +0000186 target = thread.GetProcess().GetTarget()
187
Johnny Chen1605cf62010-09-08 22:54:46 +0000188 depth = thread.GetNumFrames()
189
190 mods = GetModuleNames(thread)
191 funcs = GetFunctionNames(thread)
Johnny Chenb51d87d2010-10-07 21:38:28 +0000192 symbols = GetSymbolNames(thread)
Johnny Chen1605cf62010-09-08 22:54:46 +0000193 files = GetFilenames(thread)
194 lines = GetLineNumbers(thread)
Johnny Chenb51d87d2010-10-07 21:38:28 +0000195 addrs = GetPCAddresses(thread)
Johnny Chen30425e92010-10-07 18:52:48 +0000196
Johnny Chenad5fd402010-10-25 19:13:52 +0000197 if thread.GetStopReason() != lldb.eStopReasonInvalid:
198 desc = "stop reason=" + StopReasonString(thread.GetStopReason())
199 else:
200 desc = ""
201 print >> output, "Stack trace for thread id={0:#x} name={1} queue={2} ".format(
202 thread.GetThreadID(), thread.GetName(), thread.GetQueueName()) + desc
Johnny Chen1605cf62010-09-08 22:54:46 +0000203
Johnny Chenb51d87d2010-10-07 21:38:28 +0000204 for i in range(depth):
205 frame = thread.GetFrameAtIndex(i)
206 function = frame.GetFunction()
Johnny Chen1605cf62010-09-08 22:54:46 +0000207
Johnny Chenb51d87d2010-10-07 21:38:28 +0000208 load_addr = addrs[i].GetLoadAddress(target)
209 if not function.IsValid():
210 file_addr = addrs[i].GetFileAddress()
211 print >> output, " frame #{num}: {addr:#016x} {mod}`{symbol} + ????".format(
212 num=i, addr=load_addr, mod=mods[i], symbol=symbols[i])
213 else:
214 print >> output, " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line}".format(
215 num=i, addr=load_addr, mod=mods[i], func=funcs[i], file=files[i], line=lines[i])
216
217 if string_buffer:
Johnny Chened5f04e2010-10-15 23:33:18 +0000218 return output.getvalue()
Johnny Chenb51d87d2010-10-07 21:38:28 +0000219
220
221def PrintStackTraces(process, string_buffer = False):
222 """Prints the stack traces of all the threads."""
223
Johnny Chened5f04e2010-10-15 23:33:18 +0000224 output = StringIO.StringIO() if string_buffer else sys.stdout
Johnny Chenb51d87d2010-10-07 21:38:28 +0000225
226 print >> output, "Stack traces for " + repr(process)
227
228 for i in range(process.GetNumThreads()):
229 print >> output, PrintStackTrace(process.GetThreadAtIndex(i), string_buffer=True)
Johnny Chen30425e92010-10-07 18:52:48 +0000230
231 if string_buffer:
Johnny Chened5f04e2010-10-15 23:33:18 +0000232 return output.getvalue()