blob: a7fcee8a16a16cfdd9ecab72f92e2d40ed0dbd76 [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 Chen30e48502011-05-13 21:55:30 +00003Some of the test suite takes advantage of the utility functions defined here.
4They can also be useful for general purpose lldb scripting.
Johnny Chen1605cf62010-09-08 22:54:46 +00005"""
6
7import lldb
Johnny Chen0bfa8592011-03-23 20:28:59 +00008import os, sys
Johnny Chened5f04e2010-10-15 23:33:18 +00009import StringIO
Johnny Chen1605cf62010-09-08 22:54:46 +000010
Johnny Chen8a3b54e2011-04-26 23:07:40 +000011# ===================================================
12# Utilities for locating/checking executable programs
13# ===================================================
Johnny Chen979cb5d2011-04-26 22:53:38 +000014
Johnny Chen0bfa8592011-03-23 20:28:59 +000015def is_exe(fpath):
Johnny Chenefdc26a2011-04-26 23:10:15 +000016 """Returns True if fpath is an executable."""
Johnny Chen0bfa8592011-03-23 20:28:59 +000017 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
18
Johnny Chen0bfa8592011-03-23 20:28:59 +000019def which(program):
Johnny Chenefdc26a2011-04-26 23:10:15 +000020 """Returns the full path to a program; None otherwise."""
Johnny Chen0bfa8592011-03-23 20:28:59 +000021 fpath, fname = os.path.split(program)
22 if fpath:
23 if is_exe(program):
24 return program
25 else:
26 for path in os.environ["PATH"].split(os.pathsep):
27 exe_file = os.path.join(path, program)
28 if is_exe(exe_file):
29 return exe_file
30 return None
31
Johnny Chen51ed1b62011-03-03 19:14:00 +000032# ===================================================
33# Disassembly for an SBFunction or an SBSymbol object
34# ===================================================
35
36def disassemble(target, function_or_symbol):
37 """Disassemble the function or symbol given a target.
38
39 It returns the disassembly content in a string object.
40 """
41 buf = StringIO.StringIO()
42 insts = function_or_symbol.GetInstructions(target)
Johnny Chend643c082011-04-28 22:57:01 +000043 for i in insts:
Johnny Chen51ed1b62011-03-03 19:14:00 +000044 print >> buf, i
45 return buf.getvalue()
46
Johnny Chen4c70f282011-03-02 01:36:45 +000047# ==========================================================
48# Integer (byte size 1, 2, 4, and 8) to bytearray conversion
49# ==========================================================
50
51def int_to_bytearray(val, bytesize):
52 """Utility function to convert an integer into a bytearray.
53
Johnny Chend2765fc2011-03-02 20:54:22 +000054 It returns the bytearray in the little endian format. It is easy to get the
55 big endian format, just do ba.reverse() on the returned object.
Johnny Chen4c70f282011-03-02 01:36:45 +000056 """
Johnny Chenf4c0d1d2011-03-30 17:54:35 +000057 import struct
Johnny Chen4c70f282011-03-02 01:36:45 +000058
59 if bytesize == 1:
60 return bytearray([val])
61
62 # Little endian followed by a format character.
63 template = "<%c"
64 if bytesize == 2:
65 fmt = template % 'h'
66 elif bytesize == 4:
67 fmt = template % 'i'
68 elif bytesize == 4:
69 fmt = template % 'q'
70 else:
71 return None
72
Johnny Chenf4c0d1d2011-03-30 17:54:35 +000073 packed = struct.pack(fmt, val)
Johnny Chen4c70f282011-03-02 01:36:45 +000074 return bytearray(map(ord, packed))
75
76def bytearray_to_int(bytes, bytesize):
77 """Utility function to convert a bytearray into an integer.
78
Johnny Chend2765fc2011-03-02 20:54:22 +000079 It interprets the bytearray in the little endian format. For a big endian
80 bytearray, just do ba.reverse() on the object before passing it in.
Johnny Chen4c70f282011-03-02 01:36:45 +000081 """
Johnny Chenf4c0d1d2011-03-30 17:54:35 +000082 import struct
Johnny Chen4c70f282011-03-02 01:36:45 +000083
84 if bytesize == 1:
Filipe Cabecinhas1ee6d9f2012-07-06 16:20:13 +000085 return bytes[0]
Johnny Chen4c70f282011-03-02 01:36:45 +000086
87 # Little endian followed by a format character.
88 template = "<%c"
89 if bytesize == 2:
90 fmt = template % 'h'
91 elif bytesize == 4:
92 fmt = template % 'i'
93 elif bytesize == 4:
94 fmt = template % 'q'
95 else:
96 return None
97
Johnny Chenf4c0d1d2011-03-30 17:54:35 +000098 unpacked = struct.unpack(fmt, str(bytes))
Johnny Chen4c70f282011-03-02 01:36:45 +000099 return unpacked[0]
100
101
Johnny Chenbc1a93e2011-04-23 00:13:34 +0000102# ==============================================================
103# Get the description of an lldb object or None if not available
104# ==============================================================
Johnny Chenbdc36bd2011-04-25 20:23:05 +0000105def get_description(obj, option=None):
106 """Calls lldb_obj.GetDescription() and returns a string, or None.
107
Johnny Chenecd4feb2011-10-14 00:42:25 +0000108 For SBTarget, SBBreakpointLocation, and SBWatchpoint lldb objects, an extra
109 option can be passed in to describe the detailed level of description
110 desired:
Johnny Chenbdc36bd2011-04-25 20:23:05 +0000111 o lldb.eDescriptionLevelBrief
112 o lldb.eDescriptionLevelFull
113 o lldb.eDescriptionLevelVerbose
114 """
115 method = getattr(obj, 'GetDescription')
Johnny Chenbc1a93e2011-04-23 00:13:34 +0000116 if not method:
117 return None
Johnny Chenecd4feb2011-10-14 00:42:25 +0000118 tuple = (lldb.SBTarget, lldb.SBBreakpointLocation, lldb.SBWatchpoint)
Johnny Chen8a0d8972011-09-27 21:27:19 +0000119 if isinstance(obj, tuple):
Johnny Chenbdc36bd2011-04-25 20:23:05 +0000120 if option is None:
121 option = lldb.eDescriptionLevelBrief
122
Johnny Chenbc1a93e2011-04-23 00:13:34 +0000123 stream = lldb.SBStream()
124 if option is None:
125 success = method(stream)
126 else:
127 success = method(stream, option)
128 if not success:
129 return None
130 return stream.GetData()
131
132
Johnny Chen168a61a2010-10-22 21:31:03 +0000133# =================================================
134# Convert some enum value to its string counterpart
135# =================================================
Johnny Chenbe683bc2010-10-07 22:15:58 +0000136
Johnny Chen47342d52011-04-27 17:43:07 +0000137def state_type_to_str(enum):
Johnny Chenbe683bc2010-10-07 22:15:58 +0000138 """Returns the stateType string given an enum."""
139 if enum == lldb.eStateInvalid:
Johnny Chen59b84772010-10-18 15:46:54 +0000140 return "invalid"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000141 elif enum == lldb.eStateUnloaded:
Johnny Chen59b84772010-10-18 15:46:54 +0000142 return "unloaded"
Johnny Chen42da4da2011-03-05 01:20:11 +0000143 elif enum == lldb.eStateConnected:
144 return "connected"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000145 elif enum == lldb.eStateAttaching:
Johnny Chen59b84772010-10-18 15:46:54 +0000146 return "attaching"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000147 elif enum == lldb.eStateLaunching:
Johnny Chen59b84772010-10-18 15:46:54 +0000148 return "launching"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000149 elif enum == lldb.eStateStopped:
Johnny Chen59b84772010-10-18 15:46:54 +0000150 return "stopped"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000151 elif enum == lldb.eStateRunning:
Johnny Chen59b84772010-10-18 15:46:54 +0000152 return "running"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000153 elif enum == lldb.eStateStepping:
Johnny Chen59b84772010-10-18 15:46:54 +0000154 return "stepping"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000155 elif enum == lldb.eStateCrashed:
Johnny Chen59b84772010-10-18 15:46:54 +0000156 return "crashed"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000157 elif enum == lldb.eStateDetached:
Johnny Chen59b84772010-10-18 15:46:54 +0000158 return "detached"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000159 elif enum == lldb.eStateExited:
Johnny Chen59b84772010-10-18 15:46:54 +0000160 return "exited"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000161 elif enum == lldb.eStateSuspended:
Johnny Chen59b84772010-10-18 15:46:54 +0000162 return "suspended"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000163 else:
Johnny Chen42da4da2011-03-05 01:20:11 +0000164 raise Exception("Unknown StateType enum")
Johnny Chenbe683bc2010-10-07 22:15:58 +0000165
Johnny Chen47342d52011-04-27 17:43:07 +0000166def stop_reason_to_str(enum):
Johnny Chenbe683bc2010-10-07 22:15:58 +0000167 """Returns the stopReason string given an enum."""
168 if enum == lldb.eStopReasonInvalid:
Johnny Chen59b84772010-10-18 15:46:54 +0000169 return "invalid"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000170 elif enum == lldb.eStopReasonNone:
Johnny Chen59b84772010-10-18 15:46:54 +0000171 return "none"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000172 elif enum == lldb.eStopReasonTrace:
Johnny Chen59b84772010-10-18 15:46:54 +0000173 return "trace"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000174 elif enum == lldb.eStopReasonBreakpoint:
Johnny Chen59b84772010-10-18 15:46:54 +0000175 return "breakpoint"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000176 elif enum == lldb.eStopReasonWatchpoint:
Johnny Chen59b84772010-10-18 15:46:54 +0000177 return "watchpoint"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000178 elif enum == lldb.eStopReasonSignal:
Johnny Chen59b84772010-10-18 15:46:54 +0000179 return "signal"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000180 elif enum == lldb.eStopReasonException:
Johnny Chen59b84772010-10-18 15:46:54 +0000181 return "exception"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000182 elif enum == lldb.eStopReasonPlanComplete:
Johnny Chen59b84772010-10-18 15:46:54 +0000183 return "plancomplete"
Daniel Maleaff5c6d92013-07-09 00:08:01 +0000184 elif enum == lldb.eStopReasonThreadExiting:
185 return "threadexiting"
Johnny Chenbe683bc2010-10-07 22:15:58 +0000186 else:
Johnny Chen42da4da2011-03-05 01:20:11 +0000187 raise Exception("Unknown StopReason enum")
Johnny Chenbe683bc2010-10-07 22:15:58 +0000188
Johnny Chene7082612011-09-28 00:51:00 +0000189def symbol_type_to_str(enum):
190 """Returns the symbolType string given an enum."""
191 if enum == lldb.eSymbolTypeInvalid:
192 return "invalid"
193 elif enum == lldb.eSymbolTypeAbsolute:
194 return "absolute"
Johnny Chene7082612011-09-28 00:51:00 +0000195 elif enum == lldb.eSymbolTypeCode:
196 return "code"
197 elif enum == lldb.eSymbolTypeData:
198 return "data"
199 elif enum == lldb.eSymbolTypeTrampoline:
200 return "trampoline"
201 elif enum == lldb.eSymbolTypeRuntime:
202 return "runtime"
203 elif enum == lldb.eSymbolTypeException:
204 return "exception"
205 elif enum == lldb.eSymbolTypeSourceFile:
206 return "sourcefile"
207 elif enum == lldb.eSymbolTypeHeaderFile:
208 return "headerfile"
209 elif enum == lldb.eSymbolTypeObjectFile:
210 return "objectfile"
211 elif enum == lldb.eSymbolTypeCommonBlock:
212 return "commonblock"
213 elif enum == lldb.eSymbolTypeBlock:
214 return "block"
215 elif enum == lldb.eSymbolTypeLocal:
216 return "local"
217 elif enum == lldb.eSymbolTypeParam:
218 return "param"
219 elif enum == lldb.eSymbolTypeVariable:
220 return "variable"
221 elif enum == lldb.eSymbolTypeVariableType:
222 return "variabletype"
223 elif enum == lldb.eSymbolTypeLineEntry:
224 return "lineentry"
225 elif enum == lldb.eSymbolTypeLineHeader:
226 return "lineheader"
227 elif enum == lldb.eSymbolTypeScopeBegin:
228 return "scopebegin"
229 elif enum == lldb.eSymbolTypeScopeEnd:
230 return "scopeend"
231 elif enum == lldb.eSymbolTypeAdditional:
232 return "additional"
233 elif enum == lldb.eSymbolTypeCompiler:
234 return "compiler"
235 elif enum == lldb.eSymbolTypeInstrumentation:
236 return "instrumentation"
237 elif enum == lldb.eSymbolTypeUndefined:
238 return "undefined"
239
Johnny Chen47342d52011-04-27 17:43:07 +0000240def value_type_to_str(enum):
Johnny Chen2c8d1592010-11-03 21:37:58 +0000241 """Returns the valueType string given an enum."""
242 if enum == lldb.eValueTypeInvalid:
243 return "invalid"
244 elif enum == lldb.eValueTypeVariableGlobal:
245 return "global_variable"
246 elif enum == lldb.eValueTypeVariableStatic:
247 return "static_variable"
248 elif enum == lldb.eValueTypeVariableArgument:
249 return "argument_variable"
250 elif enum == lldb.eValueTypeVariableLocal:
251 return "local_variable"
252 elif enum == lldb.eValueTypeRegister:
253 return "register"
254 elif enum == lldb.eValueTypeRegisterSet:
255 return "register_set"
256 elif enum == lldb.eValueTypeConstResult:
257 return "constant_result"
258 else:
Johnny Chen42da4da2011-03-05 01:20:11 +0000259 raise Exception("Unknown ValueType enum")
Johnny Chen2c8d1592010-11-03 21:37:58 +0000260
Johnny Chenbe683bc2010-10-07 22:15:58 +0000261
Johnny Chen168a61a2010-10-22 21:31:03 +0000262# ==================================================
Daniel Maleaff5c6d92013-07-09 00:08:01 +0000263# Get stopped threads due to each stop reason.
264# ==================================================
265
266def sort_stopped_threads(process,
267 breakpoint_threads = None,
268 crashed_threads = None,
269 watchpoint_threads = None,
270 signal_threads = None,
271 exiting_threads = None,
272 other_threads = None):
273 """ Fills array *_threads with threads stopped for the corresponding stop
274 reason.
275 """
276 for lst in [breakpoint_threads,
277 watchpoint_threads,
278 signal_threads,
279 exiting_threads,
280 other_threads]:
281 if lst is not None:
282 lst[:] = []
283
284 for thread in process:
285 dispatched = False
286 for (reason, list) in [(lldb.eStopReasonBreakpoint, breakpoint_threads),
287 (lldb.eStopReasonException, crashed_threads),
288 (lldb.eStopReasonWatchpoint, watchpoint_threads),
289 (lldb.eStopReasonSignal, signal_threads),
290 (lldb.eStopReasonThreadExiting, exiting_threads),
291 (None, other_threads)]:
292 if not dispatched and list is not None:
293 if thread.GetStopReason() == reason or reason is None:
294 list.append(thread)
295 dispatched = True
296
297# ==================================================
Jim Ingham431d8392012-09-22 00:05:11 +0000298# Utility functions for setting breakpoints
299# ==================================================
300
301def run_break_set_by_file_and_line (test, file_name, line_number, extra_options = None, num_expected_locations = 1, loc_exact=False, module_name=None):
302 """Set a breakpoint by file and line, returning the breakpoint number.
303
304 If extra_options is not None, then we append it to the breakpoint set command.
305
306 If num_expected_locations is -1 we check that we got AT LEAST one location, otherwise we check that num_expected_locations equals the number of locations.
307
308 If loc_exact is true, we check that there is one location, and that location must be at the input file and line number."""
309
310 if file_name == None:
311 command = 'breakpoint set -l %d'%(line_number)
312 else:
313 command = 'breakpoint set -f "%s" -l %d'%(file_name, line_number)
314
Greg Clayton2fcbf6e2013-01-08 00:01:36 +0000315 if module_name:
316 command += " --shlib '%s'" % (module_name)
317
Jim Ingham431d8392012-09-22 00:05:11 +0000318 if extra_options:
319 command += " " + extra_options
320
321 break_results = run_break_set_command (test, command)
322
323 if num_expected_locations == 1 and loc_exact:
324 check_breakpoint_result (test, break_results, num_locations=num_expected_locations, file_name = file_name, line_number = line_number, module_name=module_name)
325 else:
326 check_breakpoint_result (test, break_results, num_locations = num_expected_locations)
327
328 return get_bpno_from_match (break_results)
329
330def run_break_set_by_symbol (test, symbol, extra_options = None, num_expected_locations = -1, sym_exact = False, module_name=None):
331 """Set a breakpoint by symbol name. Common options are the same as run_break_set_by_file_and_line.
332
333 If sym_exact is true, then the output symbol must match the input exactly, otherwise we do a substring match."""
334 command = 'breakpoint set -n "%s"'%(symbol)
Greg Clayton2fcbf6e2013-01-08 00:01:36 +0000335
336 if module_name:
337 command += " --shlib '%s'" % (module_name)
338
Jim Ingham431d8392012-09-22 00:05:11 +0000339 if extra_options:
340 command += " " + extra_options
341
342 break_results = run_break_set_command (test, command)
343
344 if num_expected_locations == 1 and sym_exact:
345 check_breakpoint_result (test, break_results, num_locations = num_expected_locations, symbol_name = symbol, module_name=module_name)
346 else:
347 check_breakpoint_result (test, break_results, num_locations = num_expected_locations)
348
349 return get_bpno_from_match (break_results)
350
351def run_break_set_by_selector (test, selector, extra_options = None, num_expected_locations = -1, module_name=None):
352 """Set a breakpoint by selector. Common options are the same as run_break_set_by_file_and_line."""
353
Greg Clayton2fcbf6e2013-01-08 00:01:36 +0000354 command = 'breakpoint set -S "%s"' % (selector)
355
356 if module_name:
357 command += ' --shlib "%s"' % (module_name)
358
Jim Ingham431d8392012-09-22 00:05:11 +0000359 if extra_options:
360 command += " " + extra_options
361
362 break_results = run_break_set_command (test, command)
363
364 if num_expected_locations == 1:
365 check_breakpoint_result (test, break_results, num_locations = num_expected_locations, symbol_name = selector, symbol_match_exact=False, module_name=module_name)
366 else:
367 check_breakpoint_result (test, break_results, num_locations = num_expected_locations)
368
369 return get_bpno_from_match (break_results)
370
371def run_break_set_by_regexp (test, regexp, extra_options=None, num_expected_locations=-1):
372 """Set a breakpoint by regular expression match on symbol name. Common options are the same as run_break_set_by_file_and_line."""
373
374 command = 'breakpoint set -r "%s"'%(regexp)
375 if extra_options:
376 command += " " + extra_options
377
378 break_results = run_break_set_command (test, command)
379
380 check_breakpoint_result (test, break_results, num_locations=num_expected_locations)
381
382 return get_bpno_from_match (break_results)
383
384def run_break_set_by_source_regexp (test, regexp, extra_options=None, num_expected_locations=-1):
385 """Set a breakpoint by source regular expression. Common options are the same as run_break_set_by_file_and_line."""
386 command = 'breakpoint set -p "%s"'%(regexp)
387 if extra_options:
388 command += " " + extra_options
389
390 break_results = run_break_set_command (test, command)
391
392 check_breakpoint_result (test, break_results, num_locations=num_expected_locations)
393
394 return get_bpno_from_match (break_results)
395
396def run_break_set_command (test, command):
397 """Run the command passed in - it must be some break set variant - and analyze the result.
398 Returns a dictionary of information gleaned from the command-line results.
399 Will assert if the breakpoint setting fails altogether.
400
401 Dictionary will contain:
402 bpno - breakpoint of the newly created breakpoint, -1 on error.
403 num_locations - number of locations set for the breakpoint.
404
405 If there is only one location, the dictionary MAY contain:
406 file - source file name
407 line_no - source line number
408 symbol - symbol name
409 inline_symbol - inlined symbol name
410 offset - offset from the original symbol
411 module - module
412 address - address at which the breakpoint was set."""
413
414 patterns = [r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>[0-9]+) locations\.$",
415 r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>no) locations \(pending\)\.",
416 r"^Breakpoint (?P<bpno>[0-9]+): where = (?P<module>.*)`(?P<symbol>[+\-]{0,1}[^+]+)( \+ (?P<offset>[0-9]+)){0,1}( \[inlined\] (?P<inline_symbol>.*)){0,1} at (?P<file>[^:]+):(?P<line_no>[0-9]+), address = (?P<address>0x[0-9a-fA-F]+)$",
417 r"^Breakpoint (?P<bpno>[0-9]+): where = (?P<module>.*)`(?P<symbol>.*)( \+ (?P<offset>[0-9]+)){0,1}, address = (?P<address>0x[0-9a-fA-F]+)$"]
418 match_object = test.match (command, patterns)
419 break_results = match_object.groupdict()
Jim Ingham431d8392012-09-22 00:05:11 +0000420
421 # We always insert the breakpoint number, setting it to -1 if we couldn't find it
422 # Also, make sure it gets stored as an integer.
423 if not 'bpno' in break_results:
424 break_results['bpno'] = -1
425 else:
426 break_results['bpno'] = int(break_results['bpno'])
427
428 # We always insert the number of locations
429 # If ONE location is set for the breakpoint, then the output doesn't mention locations, but it has to be 1...
430 # We also make sure it is an integer.
431
432 if not 'num_locations' in break_results:
433 num_locations = 1
434 else:
435 num_locations = break_results['num_locations']
436 if num_locations == 'no':
437 num_locations = 0
438 else:
439 num_locations = int(break_results['num_locations'])
440
441 break_results['num_locations'] = num_locations
442
443 if 'line_no' in break_results:
444 break_results['line_no'] = int(break_results['line_no'])
445
446 return break_results
447
448def get_bpno_from_match (break_results):
449 return int (break_results['bpno'])
450
451def check_breakpoint_result (test, break_results, file_name=None, line_number=-1, symbol_name=None, symbol_match_exact=True, module_name=None, offset=-1, num_locations=-1):
452
453 out_num_locations = break_results['num_locations']
454
Jim Ingham431d8392012-09-22 00:05:11 +0000455 if num_locations == -1:
456 test.assertTrue (out_num_locations > 0, "Expecting one or more locations, got none.")
457 else:
458 test.assertTrue (num_locations == out_num_locations, "Expecting %d locations, got %d."%(num_locations, out_num_locations))
459
460 if file_name:
461 out_file_name = ""
462 if 'file' in break_results:
463 out_file_name = break_results['file']
464 test.assertTrue (file_name == out_file_name, "Breakpoint file name '%s' doesn't match resultant name '%s'."%(file_name, out_file_name))
465
466 if line_number != -1:
467 out_file_line = -1
468 if 'line_no' in break_results:
469 out_line_number = break_results['line_no']
470
471 test.assertTrue (line_number == out_line_number, "Breakpoint line number %s doesn't match resultant line %s."%(line_number, out_line_number))
472
473 if symbol_name:
474 out_symbol_name = ""
475 # Look first for the inlined symbol name, otherwise use the symbol name:
476 if 'inline_symbol' in break_results and break_results['inline_symbol']:
477 out_symbol_name = break_results['inline_symbol']
478 elif 'symbol' in break_results:
479 out_symbol_name = break_results['symbol']
480
481 if symbol_match_exact:
482 test.assertTrue(symbol_name == out_symbol_name, "Symbol name '%s' doesn't match resultant symbol '%s'."%(symbol_name, out_symbol_name))
483 else:
484 test.assertTrue(out_symbol_name.find(symbol_name) != -1, "Symbol name '%s' isn't in resultant symbol '%s'."%(symbol_name, out_symbol_name))
485
486 if module_name:
487 out_nodule_name = None
488 if 'module' in break_results:
489 out_module_name = break_results['module']
490
491 test.assertTrue (module_name.find(out_module_name) != -1, "Symbol module name '%s' isn't in expected module name '%s'."%(out_module_name, module_name))
492
493# ==================================================
Johnny Chen168a61a2010-10-22 21:31:03 +0000494# Utility functions related to Threads and Processes
495# ==================================================
Johnny Chenbe683bc2010-10-07 22:15:58 +0000496
Johnny Chene428d332011-04-25 22:04:05 +0000497def get_stopped_threads(process, reason):
Johnny Chen5aba3f52011-05-26 21:53:05 +0000498 """Returns the thread(s) with the specified stop reason in a list.
499
500 The list can be empty if no such thread exists.
501 """
Johnny Chene428d332011-04-25 22:04:05 +0000502 threads = []
Johnny Chend643c082011-04-28 22:57:01 +0000503 for t in process:
Johnny Chene428d332011-04-25 22:04:05 +0000504 if t.GetStopReason() == reason:
505 threads.append(t)
506 return threads
507
508def get_stopped_thread(process, reason):
509 """A convenience function which returns the first thread with the given stop
510 reason or None.
511
512 Example usages:
513
514 1. Get the stopped thread due to a breakpoint condition
515
516 ...
517 from lldbutil import get_stopped_thread
Johnny Chen3d8ae462011-06-15 22:14:12 +0000518 thread = get_stopped_thread(process, lldb.eStopReasonPlanComplete)
Greg Clayton166b89f2013-03-19 17:59:30 +0000519 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition")
Johnny Chene428d332011-04-25 22:04:05 +0000520 ...
521
522 2. Get the thread stopped due to a breakpoint
523
524 ...
525 from lldbutil import get_stopped_thread
Johnny Chen3d8ae462011-06-15 22:14:12 +0000526 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
Greg Clayton166b89f2013-03-19 17:59:30 +0000527 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint")
Johnny Chene428d332011-04-25 22:04:05 +0000528 ...
529
530 """
531 threads = get_stopped_threads(process, reason)
532 if len(threads) == 0:
533 return None
534 return threads[0]
535
Johnny Chen318aaa02011-04-25 23:38:13 +0000536def get_threads_stopped_at_breakpoint (process, bkpt):
537 """ For a stopped process returns the thread stopped at the breakpoint passed in bkpt"""
538 stopped_threads = []
539 threads = []
540
541 stopped_threads = get_stopped_threads (process, lldb.eStopReasonBreakpoint)
542
543 if len(stopped_threads) == 0:
544 return threads
545
546 for thread in stopped_threads:
Johnny Chenec954922011-12-22 20:21:46 +0000547 # Make sure we've hit our breakpoint...
Johnny Chen318aaa02011-04-25 23:38:13 +0000548 break_id = thread.GetStopReasonDataAtIndex (0)
549 if break_id == bkpt.GetID():
550 threads.append(thread)
551
552 return threads
553
554def continue_to_breakpoint (process, bkpt):
555 """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None"""
556 process.Continue()
557 if process.GetState() != lldb.eStateStopped:
558 return None
559 else:
560 return get_threads_stopped_at_breakpoint (process, bkpt)
561
Johnny Chen69af39d2011-03-09 23:45:56 +0000562def get_caller_symbol(thread):
563 """
564 Returns the symbol name for the call site of the leaf function.
565 """
566 depth = thread.GetNumFrames()
567 if depth <= 1:
568 return None
569 caller = thread.GetFrameAtIndex(1).GetSymbol()
570 if caller:
571 return caller.GetName()
572 else:
573 return None
574
575
Johnny Chen318aaa02011-04-25 23:38:13 +0000576def get_function_names(thread):
Johnny Chen1605cf62010-09-08 22:54:46 +0000577 """
578 Returns a sequence of function names from the stack frames of this thread.
579 """
580 def GetFuncName(i):
Johnny Chen64abe462011-06-20 00:26:39 +0000581 return thread.GetFrameAtIndex(i).GetFunctionName()
Johnny Chen1605cf62010-09-08 22:54:46 +0000582
583 return map(GetFuncName, range(thread.GetNumFrames()))
584
585
Johnny Chen318aaa02011-04-25 23:38:13 +0000586def get_symbol_names(thread):
Johnny Chenb51d87d2010-10-07 21:38:28 +0000587 """
588 Returns a sequence of symbols for this thread.
589 """
590 def GetSymbol(i):
591 return thread.GetFrameAtIndex(i).GetSymbol().GetName()
592
593 return map(GetSymbol, range(thread.GetNumFrames()))
594
595
Johnny Chen318aaa02011-04-25 23:38:13 +0000596def get_pc_addresses(thread):
Johnny Chenb51d87d2010-10-07 21:38:28 +0000597 """
598 Returns a sequence of pc addresses for this thread.
599 """
600 def GetPCAddress(i):
601 return thread.GetFrameAtIndex(i).GetPCAddress()
602
603 return map(GetPCAddress, range(thread.GetNumFrames()))
604
605
Johnny Chen318aaa02011-04-25 23:38:13 +0000606def get_filenames(thread):
Johnny Chen1605cf62010-09-08 22:54:46 +0000607 """
608 Returns a sequence of file names from the stack frames of this thread.
609 """
610 def GetFilename(i):
611 return thread.GetFrameAtIndex(i).GetLineEntry().GetFileSpec().GetFilename()
612
613 return map(GetFilename, range(thread.GetNumFrames()))
614
615
Johnny Chen318aaa02011-04-25 23:38:13 +0000616def get_line_numbers(thread):
Johnny Chen1605cf62010-09-08 22:54:46 +0000617 """
618 Returns a sequence of line numbers from the stack frames of this thread.
619 """
620 def GetLineNumber(i):
621 return thread.GetFrameAtIndex(i).GetLineEntry().GetLine()
622
623 return map(GetLineNumber, range(thread.GetNumFrames()))
624
625
Johnny Chen318aaa02011-04-25 23:38:13 +0000626def get_module_names(thread):
Johnny Chen1605cf62010-09-08 22:54:46 +0000627 """
628 Returns a sequence of module names from the stack frames of this thread.
629 """
630 def GetModuleName(i):
631 return thread.GetFrameAtIndex(i).GetModule().GetFileSpec().GetFilename()
632
633 return map(GetModuleName, range(thread.GetNumFrames()))
634
635
Johnny Chen318aaa02011-04-25 23:38:13 +0000636def get_stack_frames(thread):
Johnny Chen88866ac2010-09-09 00:55:07 +0000637 """
638 Returns a sequence of stack frames for this thread.
639 """
640 def GetStackFrame(i):
641 return thread.GetFrameAtIndex(i)
642
643 return map(GetStackFrame, range(thread.GetNumFrames()))
644
645
Johnny Chen318aaa02011-04-25 23:38:13 +0000646def print_stacktrace(thread, string_buffer = False):
Johnny Chen1605cf62010-09-08 22:54:46 +0000647 """Prints a simple stack trace of this thread."""
Johnny Chen30425e92010-10-07 18:52:48 +0000648
Johnny Chened5f04e2010-10-15 23:33:18 +0000649 output = StringIO.StringIO() if string_buffer else sys.stdout
Johnny Chenb51d87d2010-10-07 21:38:28 +0000650 target = thread.GetProcess().GetTarget()
651
Johnny Chen1605cf62010-09-08 22:54:46 +0000652 depth = thread.GetNumFrames()
653
Johnny Chen318aaa02011-04-25 23:38:13 +0000654 mods = get_module_names(thread)
655 funcs = get_function_names(thread)
656 symbols = get_symbol_names(thread)
657 files = get_filenames(thread)
658 lines = get_line_numbers(thread)
659 addrs = get_pc_addresses(thread)
Johnny Chen30425e92010-10-07 18:52:48 +0000660
Johnny Chenad5fd402010-10-25 19:13:52 +0000661 if thread.GetStopReason() != lldb.eStopReasonInvalid:
Johnny Chen47342d52011-04-27 17:43:07 +0000662 desc = "stop reason=" + stop_reason_to_str(thread.GetStopReason())
Johnny Chenad5fd402010-10-25 19:13:52 +0000663 else:
664 desc = ""
665 print >> output, "Stack trace for thread id={0:#x} name={1} queue={2} ".format(
666 thread.GetThreadID(), thread.GetName(), thread.GetQueueName()) + desc
Johnny Chen1605cf62010-09-08 22:54:46 +0000667
Johnny Chenb51d87d2010-10-07 21:38:28 +0000668 for i in range(depth):
669 frame = thread.GetFrameAtIndex(i)
670 function = frame.GetFunction()
Johnny Chen1605cf62010-09-08 22:54:46 +0000671
Johnny Chenb51d87d2010-10-07 21:38:28 +0000672 load_addr = addrs[i].GetLoadAddress(target)
Johnny Chen960ce122011-05-25 19:06:18 +0000673 if not function:
Johnny Chenb51d87d2010-10-07 21:38:28 +0000674 file_addr = addrs[i].GetFileAddress()
Johnny Chen49f3d812011-06-16 22:07:48 +0000675 start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress()
676 symbol_offset = file_addr - start_addr
677 print >> output, " frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format(
678 num=i, addr=load_addr, mod=mods[i], symbol=symbols[i], offset=symbol_offset)
Johnny Chenb51d87d2010-10-07 21:38:28 +0000679 else:
Johnny Chen49f3d812011-06-16 22:07:48 +0000680 print >> output, " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format(
Johnny Chen64abe462011-06-20 00:26:39 +0000681 num=i, addr=load_addr, mod=mods[i],
682 func='%s [inlined]' % funcs[i] if frame.IsInlined() else funcs[i],
Johnny Chen7d4c7fe2011-07-13 22:34:29 +0000683 file=files[i], line=lines[i],
684 args=get_args_as_string(frame, showFuncName=False) if not frame.IsInlined() else '()')
Johnny Chenb51d87d2010-10-07 21:38:28 +0000685
686 if string_buffer:
Johnny Chened5f04e2010-10-15 23:33:18 +0000687 return output.getvalue()
Johnny Chenb51d87d2010-10-07 21:38:28 +0000688
689
Johnny Chen318aaa02011-04-25 23:38:13 +0000690def print_stacktraces(process, string_buffer = False):
Johnny Chenb51d87d2010-10-07 21:38:28 +0000691 """Prints the stack traces of all the threads."""
692
Johnny Chened5f04e2010-10-15 23:33:18 +0000693 output = StringIO.StringIO() if string_buffer else sys.stdout
Johnny Chenb51d87d2010-10-07 21:38:28 +0000694
Greg Clayton0a19a1b2012-02-04 02:27:34 +0000695 print >> output, "Stack traces for " + str(process)
Johnny Chenb51d87d2010-10-07 21:38:28 +0000696
Johnny Chen311b1d62011-05-05 18:50:56 +0000697 for thread in process:
698 print >> output, print_stacktrace(thread, string_buffer=True)
Johnny Chen30425e92010-10-07 18:52:48 +0000699
700 if string_buffer:
Johnny Chened5f04e2010-10-15 23:33:18 +0000701 return output.getvalue()
Johnny Chen185e2c12011-05-08 17:25:27 +0000702
703# ===================================
704# Utility functions related to Frames
705# ===================================
706
Johnny Chenabb3b2d2011-05-12 00:32:41 +0000707def get_parent_frame(frame):
708 """
709 Returns the parent frame of the input frame object; None if not available.
710 """
711 thread = frame.GetThread()
712 parent_found = False
713 for f in thread:
714 if parent_found:
715 return f
716 if f.GetFrameID() == frame.GetFrameID():
717 parent_found = True
718
719 # If we reach here, no parent has been found, return None.
720 return None
721
Johnny Chen49f3d812011-06-16 22:07:48 +0000722def get_args_as_string(frame, showFuncName=True):
Johnny Chenabb3b2d2011-05-12 00:32:41 +0000723 """
724 Returns the args of the input frame object as a string.
725 """
726 # arguments => True
727 # locals => False
728 # statics => False
729 # in_scope_only => True
730 vars = frame.GetVariables(True, False, False, True) # type of SBValueList
731 args = [] # list of strings
732 for var in vars:
733 args.append("(%s)%s=%s" % (var.GetTypeName(),
734 var.GetName(),
Greg Clayton0fb0bcc2011-08-03 22:57:10 +0000735 var.GetValue()))
Johnny Chen960ce122011-05-25 19:06:18 +0000736 if frame.GetFunction():
Johnny Chenbbc18b62011-05-13 00:44:49 +0000737 name = frame.GetFunction().GetName()
Johnny Chen960ce122011-05-25 19:06:18 +0000738 elif frame.GetSymbol():
Johnny Chenbbc18b62011-05-13 00:44:49 +0000739 name = frame.GetSymbol().GetName()
740 else:
741 name = ""
Johnny Chen49f3d812011-06-16 22:07:48 +0000742 if showFuncName:
743 return "%s(%s)" % (name, ", ".join(args))
744 else:
745 return "(%s)" % (", ".join(args))
746
Johnny Chen185e2c12011-05-08 17:25:27 +0000747def print_registers(frame, string_buffer = False):
Johnny Chenb2998772011-05-08 18:55:37 +0000748 """Prints all the register sets of the frame."""
Johnny Chen185e2c12011-05-08 17:25:27 +0000749
750 output = StringIO.StringIO() if string_buffer else sys.stdout
751
Greg Clayton0a19a1b2012-02-04 02:27:34 +0000752 print >> output, "Register sets for " + str(frame)
Johnny Chen185e2c12011-05-08 17:25:27 +0000753
Johnny Chen728255b2011-05-10 19:21:13 +0000754 registerSet = frame.GetRegisters() # Return type of SBValueList.
755 print >> output, "Frame registers (size of register set = %d):" % registerSet.GetSize()
756 for value in registerSet:
Johnny Chen185e2c12011-05-08 17:25:27 +0000757 #print >> output, value
758 print >> output, "%s (number of children = %d):" % (value.GetName(), value.GetNumChildren())
759 for child in value:
Greg Clayton0fb0bcc2011-08-03 22:57:10 +0000760 print >> output, "Name: %s, Value: %s" % (child.GetName(), child.GetValue())
Johnny Chen185e2c12011-05-08 17:25:27 +0000761
762 if string_buffer:
763 return output.getvalue()
Johnny Chen728255b2011-05-10 19:21:13 +0000764
765def get_registers(frame, kind):
766 """Returns the registers given the frame and the kind of registers desired.
767
768 Returns None if there's no such kind.
769 """
770 registerSet = frame.GetRegisters() # Return type of SBValueList.
771 for value in registerSet:
772 if kind.lower() in value.GetName().lower():
773 return value
774
775 return None
776
777def get_GPRs(frame):
778 """Returns the general purpose registers of the frame as an SBValue.
779
Johnny Chenfd1175c2011-05-10 23:01:44 +0000780 The returned SBValue object is iterable. An example:
781 ...
782 from lldbutil import get_GPRs
783 regs = get_GPRs(frame)
784 for reg in regs:
785 print "%s => %s" % (reg.GetName(), reg.GetValue())
786 ...
Johnny Chen728255b2011-05-10 19:21:13 +0000787 """
788 return get_registers(frame, "general purpose")
789
790def get_FPRs(frame):
791 """Returns the floating point registers of the frame as an SBValue.
792
Johnny Chenfd1175c2011-05-10 23:01:44 +0000793 The returned SBValue object is iterable. An example:
794 ...
795 from lldbutil import get_FPRs
796 regs = get_FPRs(frame)
797 for reg in regs:
798 print "%s => %s" % (reg.GetName(), reg.GetValue())
799 ...
Johnny Chen728255b2011-05-10 19:21:13 +0000800 """
801 return get_registers(frame, "floating point")
802
803def get_ESRs(frame):
804 """Returns the exception state registers of the frame as an SBValue.
805
Johnny Chenfd1175c2011-05-10 23:01:44 +0000806 The returned SBValue object is iterable. An example:
807 ...
808 from lldbutil import get_ESRs
809 regs = get_ESRs(frame)
810 for reg in regs:
811 print "%s => %s" % (reg.GetName(), reg.GetValue())
812 ...
Johnny Chen728255b2011-05-10 19:21:13 +0000813 """
814 return get_registers(frame, "exception state")
Johnny Chen084fd892011-07-22 00:47:58 +0000815
Johnny Chen8c062762011-07-22 00:51:54 +0000816# ======================================
817# Utility classes/functions for SBValues
818# ======================================
Johnny Chen084fd892011-07-22 00:47:58 +0000819
820class BasicFormatter(object):
Johnny Chen638ebcf2011-07-22 22:01:35 +0000821 """The basic formatter inspects the value object and prints the value."""
Johnny Chen084fd892011-07-22 00:47:58 +0000822 def format(self, value, buffer=None, indent=0):
823 if not buffer:
824 output = StringIO.StringIO()
825 else:
826 output = buffer
Johnny Chen638ebcf2011-07-22 22:01:35 +0000827 # If there is a summary, it suffices.
828 val = value.GetSummary()
829 # Otherwise, get the value.
830 if val == None:
831 val = value.GetValue()
832 if val == None and value.GetNumChildren() > 0:
833 val = "%s (location)" % value.GetLocation()
834 print >> output, "{indentation}({type}) {name} = {value}".format(
Johnny Chen084fd892011-07-22 00:47:58 +0000835 indentation = ' ' * indent,
836 type = value.GetTypeName(),
837 name = value.GetName(),
Johnny Chen638ebcf2011-07-22 22:01:35 +0000838 value = val)
Johnny Chen084fd892011-07-22 00:47:58 +0000839 return output.getvalue()
840
841class ChildVisitingFormatter(BasicFormatter):
Johnny Chen638ebcf2011-07-22 22:01:35 +0000842 """The child visiting formatter prints the value and its immediate children.
843
844 The constructor takes a keyword arg: indent_child, which defaults to 2.
845 """
846 def __init__(self, indent_child=2):
847 """Default indentation of 2 SPC's for the children."""
848 self.cindent = indent_child
Johnny Chen084fd892011-07-22 00:47:58 +0000849 def format(self, value, buffer=None):
850 if not buffer:
851 output = StringIO.StringIO()
852 else:
853 output = buffer
854
855 BasicFormatter.format(self, value, buffer=output)
856 for child in value:
Johnny Chen638ebcf2011-07-22 22:01:35 +0000857 BasicFormatter.format(self, child, buffer=output, indent=self.cindent)
858
859 return output.getvalue()
860
861class RecursiveDecentFormatter(BasicFormatter):
862 """The recursive decent formatter prints the value and the decendents.
863
864 The constructor takes two keyword args: indent_level, which defaults to 0,
865 and indent_child, which defaults to 2. The current indentation level is
866 determined by indent_level, while the immediate children has an additional
867 indentation by inden_child.
868 """
869 def __init__(self, indent_level=0, indent_child=2):
870 self.lindent = indent_level
871 self.cindent = indent_child
872 def format(self, value, buffer=None):
873 if not buffer:
874 output = StringIO.StringIO()
875 else:
876 output = buffer
877
878 BasicFormatter.format(self, value, buffer=output, indent=self.lindent)
879 new_indent = self.lindent + self.cindent
880 for child in value:
881 if child.GetSummary() != None:
882 BasicFormatter.format(self, child, buffer=output, indent=new_indent)
883 else:
884 if child.GetNumChildren() > 0:
885 rdf = RecursiveDecentFormatter(indent_level=new_indent)
886 rdf.format(child, buffer=output)
887 else:
888 BasicFormatter.format(self, child, buffer=output, indent=new_indent)
Johnny Chen084fd892011-07-22 00:47:58 +0000889
890 return output.getvalue()