blob: 6951a33888eb698134882f67eb21b9ff43e2087b [file] [log] [blame]
Johnny Chen30ee4ef2010-09-08 22:54:46 +00001"""
Johnny Chen7ea9aee2010-10-07 21:38:28 +00002This LLDB module contains miscellaneous utilities.
Johnny Chenb411b982011-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 Chen30ee4ef2010-09-08 22:54:46 +00005"""
6
7import lldb
Johnny Chenac77f3b2011-03-23 20:28:59 +00008import os, sys
Johnny Chend5d6fac2010-10-15 23:33:18 +00009import StringIO
Johnny Chen30ee4ef2010-09-08 22:54:46 +000010
Johnny Chen6424b7d2011-04-26 23:07:40 +000011# ===================================================
12# Utilities for locating/checking executable programs
13# ===================================================
Johnny Chen4fdcebd2011-04-26 22:53:38 +000014
Johnny Chenac77f3b2011-03-23 20:28:59 +000015def is_exe(fpath):
Johnny Chen35ec6742011-04-26 23:10:15 +000016 """Returns True if fpath is an executable."""
Johnny Chenac77f3b2011-03-23 20:28:59 +000017 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
18
Johnny Chenac77f3b2011-03-23 20:28:59 +000019def which(program):
Johnny Chen35ec6742011-04-26 23:10:15 +000020 """Returns the full path to a program; None otherwise."""
Johnny Chenac77f3b2011-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 Chened401982011-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 Chene69c7482011-04-28 22:57:01 +000043 for i in insts:
Johnny Chened401982011-03-03 19:14:00 +000044 print >> buf, i
45 return buf.getvalue()
46
Johnny Chen43766d62011-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 Chen43e587c2011-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 Chen43766d62011-03-02 01:36:45 +000056 """
Johnny Chen90bb9052011-03-30 17:54:35 +000057 import struct
Johnny Chen43766d62011-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 Chen90bb9052011-03-30 17:54:35 +000073 packed = struct.pack(fmt, val)
Johnny Chen43766d62011-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 Chen43e587c2011-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 Chen43766d62011-03-02 01:36:45 +000081 """
Johnny Chen90bb9052011-03-30 17:54:35 +000082 import struct
Johnny Chen43766d62011-03-02 01:36:45 +000083
84 if bytesize == 1:
Filipe Cabecinhas5d261b02012-07-06 16:20:13 +000085 return bytes[0]
Johnny Chen43766d62011-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 Chen90bb9052011-03-30 17:54:35 +000098 unpacked = struct.unpack(fmt, str(bytes))
Johnny Chen43766d62011-03-02 01:36:45 +000099 return unpacked[0]
100
101
Johnny Chen90256cd2011-04-23 00:13:34 +0000102# ==============================================================
103# Get the description of an lldb object or None if not available
104# ==============================================================
Johnny Chenfc87e2d2011-04-25 20:23:05 +0000105def get_description(obj, option=None):
106 """Calls lldb_obj.GetDescription() and returns a string, or None.
107
Johnny Chen01a67862011-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 Chenfc87e2d2011-04-25 20:23:05 +0000111 o lldb.eDescriptionLevelBrief
112 o lldb.eDescriptionLevelFull
113 o lldb.eDescriptionLevelVerbose
114 """
115 method = getattr(obj, 'GetDescription')
Johnny Chen90256cd2011-04-23 00:13:34 +0000116 if not method:
117 return None
Johnny Chen01a67862011-10-14 00:42:25 +0000118 tuple = (lldb.SBTarget, lldb.SBBreakpointLocation, lldb.SBWatchpoint)
Johnny Chen469683e2011-09-27 21:27:19 +0000119 if isinstance(obj, tuple):
Johnny Chenfc87e2d2011-04-25 20:23:05 +0000120 if option is None:
121 option = lldb.eDescriptionLevelBrief
122
Johnny Chen90256cd2011-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 Chenf4f70bb2010-10-22 21:31:03 +0000133# =================================================
134# Convert some enum value to its string counterpart
135# =================================================
Johnny Chen28ae2942010-10-07 22:15:58 +0000136
Johnny Chende90f1d2011-04-27 17:43:07 +0000137def state_type_to_str(enum):
Johnny Chen28ae2942010-10-07 22:15:58 +0000138 """Returns the stateType string given an enum."""
139 if enum == lldb.eStateInvalid:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000140 return "invalid"
Johnny Chen28ae2942010-10-07 22:15:58 +0000141 elif enum == lldb.eStateUnloaded:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000142 return "unloaded"
Johnny Chen930e3ad2011-03-05 01:20:11 +0000143 elif enum == lldb.eStateConnected:
144 return "connected"
Johnny Chen28ae2942010-10-07 22:15:58 +0000145 elif enum == lldb.eStateAttaching:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000146 return "attaching"
Johnny Chen28ae2942010-10-07 22:15:58 +0000147 elif enum == lldb.eStateLaunching:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000148 return "launching"
Johnny Chen28ae2942010-10-07 22:15:58 +0000149 elif enum == lldb.eStateStopped:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000150 return "stopped"
Johnny Chen28ae2942010-10-07 22:15:58 +0000151 elif enum == lldb.eStateRunning:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000152 return "running"
Johnny Chen28ae2942010-10-07 22:15:58 +0000153 elif enum == lldb.eStateStepping:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000154 return "stepping"
Johnny Chen28ae2942010-10-07 22:15:58 +0000155 elif enum == lldb.eStateCrashed:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000156 return "crashed"
Johnny Chen28ae2942010-10-07 22:15:58 +0000157 elif enum == lldb.eStateDetached:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000158 return "detached"
Johnny Chen28ae2942010-10-07 22:15:58 +0000159 elif enum == lldb.eStateExited:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000160 return "exited"
Johnny Chen28ae2942010-10-07 22:15:58 +0000161 elif enum == lldb.eStateSuspended:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000162 return "suspended"
Johnny Chen28ae2942010-10-07 22:15:58 +0000163 else:
Johnny Chen930e3ad2011-03-05 01:20:11 +0000164 raise Exception("Unknown StateType enum")
Johnny Chen28ae2942010-10-07 22:15:58 +0000165
Johnny Chende90f1d2011-04-27 17:43:07 +0000166def stop_reason_to_str(enum):
Johnny Chen28ae2942010-10-07 22:15:58 +0000167 """Returns the stopReason string given an enum."""
168 if enum == lldb.eStopReasonInvalid:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000169 return "invalid"
Johnny Chen28ae2942010-10-07 22:15:58 +0000170 elif enum == lldb.eStopReasonNone:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000171 return "none"
Johnny Chen28ae2942010-10-07 22:15:58 +0000172 elif enum == lldb.eStopReasonTrace:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000173 return "trace"
Johnny Chen28ae2942010-10-07 22:15:58 +0000174 elif enum == lldb.eStopReasonBreakpoint:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000175 return "breakpoint"
Johnny Chen28ae2942010-10-07 22:15:58 +0000176 elif enum == lldb.eStopReasonWatchpoint:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000177 return "watchpoint"
Jim Ingham6cc0d2f2014-04-03 01:25:28 +0000178 elif enum == lldb.eStopReasonExec:
179 return "exec"
Johnny Chen28ae2942010-10-07 22:15:58 +0000180 elif enum == lldb.eStopReasonSignal:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000181 return "signal"
Johnny Chen28ae2942010-10-07 22:15:58 +0000182 elif enum == lldb.eStopReasonException:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000183 return "exception"
Johnny Chen28ae2942010-10-07 22:15:58 +0000184 elif enum == lldb.eStopReasonPlanComplete:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000185 return "plancomplete"
Daniel Maleab3d41a22013-07-09 00:08:01 +0000186 elif enum == lldb.eStopReasonThreadExiting:
187 return "threadexiting"
Johnny Chen28ae2942010-10-07 22:15:58 +0000188 else:
Johnny Chen930e3ad2011-03-05 01:20:11 +0000189 raise Exception("Unknown StopReason enum")
Johnny Chen28ae2942010-10-07 22:15:58 +0000190
Johnny Chena32a13d2011-09-28 00:51:00 +0000191def symbol_type_to_str(enum):
192 """Returns the symbolType string given an enum."""
193 if enum == lldb.eSymbolTypeInvalid:
194 return "invalid"
195 elif enum == lldb.eSymbolTypeAbsolute:
196 return "absolute"
Johnny Chena32a13d2011-09-28 00:51:00 +0000197 elif enum == lldb.eSymbolTypeCode:
198 return "code"
199 elif enum == lldb.eSymbolTypeData:
200 return "data"
201 elif enum == lldb.eSymbolTypeTrampoline:
202 return "trampoline"
203 elif enum == lldb.eSymbolTypeRuntime:
204 return "runtime"
205 elif enum == lldb.eSymbolTypeException:
206 return "exception"
207 elif enum == lldb.eSymbolTypeSourceFile:
208 return "sourcefile"
209 elif enum == lldb.eSymbolTypeHeaderFile:
210 return "headerfile"
211 elif enum == lldb.eSymbolTypeObjectFile:
212 return "objectfile"
213 elif enum == lldb.eSymbolTypeCommonBlock:
214 return "commonblock"
215 elif enum == lldb.eSymbolTypeBlock:
216 return "block"
217 elif enum == lldb.eSymbolTypeLocal:
218 return "local"
219 elif enum == lldb.eSymbolTypeParam:
220 return "param"
221 elif enum == lldb.eSymbolTypeVariable:
222 return "variable"
223 elif enum == lldb.eSymbolTypeVariableType:
224 return "variabletype"
225 elif enum == lldb.eSymbolTypeLineEntry:
226 return "lineentry"
227 elif enum == lldb.eSymbolTypeLineHeader:
228 return "lineheader"
229 elif enum == lldb.eSymbolTypeScopeBegin:
230 return "scopebegin"
231 elif enum == lldb.eSymbolTypeScopeEnd:
232 return "scopeend"
233 elif enum == lldb.eSymbolTypeAdditional:
234 return "additional"
235 elif enum == lldb.eSymbolTypeCompiler:
236 return "compiler"
237 elif enum == lldb.eSymbolTypeInstrumentation:
238 return "instrumentation"
239 elif enum == lldb.eSymbolTypeUndefined:
240 return "undefined"
241
Johnny Chende90f1d2011-04-27 17:43:07 +0000242def value_type_to_str(enum):
Johnny Chen87bb5892010-11-03 21:37:58 +0000243 """Returns the valueType string given an enum."""
244 if enum == lldb.eValueTypeInvalid:
245 return "invalid"
246 elif enum == lldb.eValueTypeVariableGlobal:
247 return "global_variable"
248 elif enum == lldb.eValueTypeVariableStatic:
249 return "static_variable"
250 elif enum == lldb.eValueTypeVariableArgument:
251 return "argument_variable"
252 elif enum == lldb.eValueTypeVariableLocal:
253 return "local_variable"
254 elif enum == lldb.eValueTypeRegister:
255 return "register"
256 elif enum == lldb.eValueTypeRegisterSet:
257 return "register_set"
258 elif enum == lldb.eValueTypeConstResult:
259 return "constant_result"
260 else:
Johnny Chen930e3ad2011-03-05 01:20:11 +0000261 raise Exception("Unknown ValueType enum")
Johnny Chen87bb5892010-11-03 21:37:58 +0000262
Johnny Chen28ae2942010-10-07 22:15:58 +0000263
Johnny Chenf4f70bb2010-10-22 21:31:03 +0000264# ==================================================
Daniel Maleab3d41a22013-07-09 00:08:01 +0000265# Get stopped threads due to each stop reason.
266# ==================================================
267
268def sort_stopped_threads(process,
269 breakpoint_threads = None,
270 crashed_threads = None,
271 watchpoint_threads = None,
272 signal_threads = None,
273 exiting_threads = None,
274 other_threads = None):
275 """ Fills array *_threads with threads stopped for the corresponding stop
276 reason.
277 """
278 for lst in [breakpoint_threads,
279 watchpoint_threads,
280 signal_threads,
281 exiting_threads,
282 other_threads]:
283 if lst is not None:
284 lst[:] = []
285
286 for thread in process:
287 dispatched = False
288 for (reason, list) in [(lldb.eStopReasonBreakpoint, breakpoint_threads),
289 (lldb.eStopReasonException, crashed_threads),
290 (lldb.eStopReasonWatchpoint, watchpoint_threads),
291 (lldb.eStopReasonSignal, signal_threads),
292 (lldb.eStopReasonThreadExiting, exiting_threads),
293 (None, other_threads)]:
294 if not dispatched and list is not None:
295 if thread.GetStopReason() == reason or reason is None:
296 list.append(thread)
297 dispatched = True
298
299# ==================================================
Jim Ingham63dfc722012-09-22 00:05:11 +0000300# Utility functions for setting breakpoints
301# ==================================================
302
303def 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):
304 """Set a breakpoint by file and line, returning the breakpoint number.
305
306 If extra_options is not None, then we append it to the breakpoint set command.
307
308 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.
309
310 If loc_exact is true, we check that there is one location, and that location must be at the input file and line number."""
311
312 if file_name == None:
313 command = 'breakpoint set -l %d'%(line_number)
314 else:
315 command = 'breakpoint set -f "%s" -l %d'%(file_name, line_number)
316
Greg Claytonc1b2ccf2013-01-08 00:01:36 +0000317 if module_name:
318 command += " --shlib '%s'" % (module_name)
319
Jim Ingham63dfc722012-09-22 00:05:11 +0000320 if extra_options:
321 command += " " + extra_options
322
323 break_results = run_break_set_command (test, command)
324
325 if num_expected_locations == 1 and loc_exact:
326 check_breakpoint_result (test, break_results, num_locations=num_expected_locations, file_name = file_name, line_number = line_number, module_name=module_name)
327 else:
328 check_breakpoint_result (test, break_results, num_locations = num_expected_locations)
329
330 return get_bpno_from_match (break_results)
331
332def run_break_set_by_symbol (test, symbol, extra_options = None, num_expected_locations = -1, sym_exact = False, module_name=None):
333 """Set a breakpoint by symbol name. Common options are the same as run_break_set_by_file_and_line.
334
335 If sym_exact is true, then the output symbol must match the input exactly, otherwise we do a substring match."""
336 command = 'breakpoint set -n "%s"'%(symbol)
Greg Claytonc1b2ccf2013-01-08 00:01:36 +0000337
338 if module_name:
339 command += " --shlib '%s'" % (module_name)
340
Jim Ingham63dfc722012-09-22 00:05:11 +0000341 if extra_options:
342 command += " " + extra_options
343
344 break_results = run_break_set_command (test, command)
345
346 if num_expected_locations == 1 and sym_exact:
347 check_breakpoint_result (test, break_results, num_locations = num_expected_locations, symbol_name = symbol, module_name=module_name)
348 else:
349 check_breakpoint_result (test, break_results, num_locations = num_expected_locations)
350
351 return get_bpno_from_match (break_results)
352
353def run_break_set_by_selector (test, selector, extra_options = None, num_expected_locations = -1, module_name=None):
354 """Set a breakpoint by selector. Common options are the same as run_break_set_by_file_and_line."""
355
Greg Claytonc1b2ccf2013-01-08 00:01:36 +0000356 command = 'breakpoint set -S "%s"' % (selector)
357
358 if module_name:
359 command += ' --shlib "%s"' % (module_name)
360
Jim Ingham63dfc722012-09-22 00:05:11 +0000361 if extra_options:
362 command += " " + extra_options
363
364 break_results = run_break_set_command (test, command)
365
366 if num_expected_locations == 1:
367 check_breakpoint_result (test, break_results, num_locations = num_expected_locations, symbol_name = selector, symbol_match_exact=False, module_name=module_name)
368 else:
369 check_breakpoint_result (test, break_results, num_locations = num_expected_locations)
370
371 return get_bpno_from_match (break_results)
372
373def run_break_set_by_regexp (test, regexp, extra_options=None, num_expected_locations=-1):
374 """Set a breakpoint by regular expression match on symbol name. Common options are the same as run_break_set_by_file_and_line."""
375
376 command = 'breakpoint set -r "%s"'%(regexp)
377 if extra_options:
378 command += " " + extra_options
379
380 break_results = run_break_set_command (test, command)
381
382 check_breakpoint_result (test, break_results, num_locations=num_expected_locations)
383
384 return get_bpno_from_match (break_results)
385
386def run_break_set_by_source_regexp (test, regexp, extra_options=None, num_expected_locations=-1):
387 """Set a breakpoint by source regular expression. Common options are the same as run_break_set_by_file_and_line."""
388 command = 'breakpoint set -p "%s"'%(regexp)
389 if extra_options:
390 command += " " + extra_options
391
392 break_results = run_break_set_command (test, command)
393
394 check_breakpoint_result (test, break_results, num_locations=num_expected_locations)
395
396 return get_bpno_from_match (break_results)
397
398def run_break_set_command (test, command):
399 """Run the command passed in - it must be some break set variant - and analyze the result.
400 Returns a dictionary of information gleaned from the command-line results.
401 Will assert if the breakpoint setting fails altogether.
402
403 Dictionary will contain:
404 bpno - breakpoint of the newly created breakpoint, -1 on error.
405 num_locations - number of locations set for the breakpoint.
406
407 If there is only one location, the dictionary MAY contain:
408 file - source file name
409 line_no - source line number
410 symbol - symbol name
411 inline_symbol - inlined symbol name
412 offset - offset from the original symbol
413 module - module
414 address - address at which the breakpoint was set."""
415
416 patterns = [r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>[0-9]+) locations\.$",
417 r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>no) locations \(pending\)\.",
418 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]+)$",
419 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]+)$"]
420 match_object = test.match (command, patterns)
421 break_results = match_object.groupdict()
Jim Ingham63dfc722012-09-22 00:05:11 +0000422
423 # We always insert the breakpoint number, setting it to -1 if we couldn't find it
424 # Also, make sure it gets stored as an integer.
425 if not 'bpno' in break_results:
426 break_results['bpno'] = -1
427 else:
428 break_results['bpno'] = int(break_results['bpno'])
429
430 # We always insert the number of locations
431 # If ONE location is set for the breakpoint, then the output doesn't mention locations, but it has to be 1...
432 # We also make sure it is an integer.
433
434 if not 'num_locations' in break_results:
435 num_locations = 1
436 else:
437 num_locations = break_results['num_locations']
438 if num_locations == 'no':
439 num_locations = 0
440 else:
441 num_locations = int(break_results['num_locations'])
442
443 break_results['num_locations'] = num_locations
444
445 if 'line_no' in break_results:
446 break_results['line_no'] = int(break_results['line_no'])
447
448 return break_results
449
450def get_bpno_from_match (break_results):
451 return int (break_results['bpno'])
452
453def 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):
454
455 out_num_locations = break_results['num_locations']
456
Jim Ingham63dfc722012-09-22 00:05:11 +0000457 if num_locations == -1:
458 test.assertTrue (out_num_locations > 0, "Expecting one or more locations, got none.")
459 else:
460 test.assertTrue (num_locations == out_num_locations, "Expecting %d locations, got %d."%(num_locations, out_num_locations))
461
462 if file_name:
463 out_file_name = ""
464 if 'file' in break_results:
465 out_file_name = break_results['file']
466 test.assertTrue (file_name == out_file_name, "Breakpoint file name '%s' doesn't match resultant name '%s'."%(file_name, out_file_name))
467
468 if line_number != -1:
Ilia K055ad9b2015-05-18 13:41:01 +0000469 out_line_number = -1
Jim Ingham63dfc722012-09-22 00:05:11 +0000470 if 'line_no' in break_results:
471 out_line_number = break_results['line_no']
472
473 test.assertTrue (line_number == out_line_number, "Breakpoint line number %s doesn't match resultant line %s."%(line_number, out_line_number))
474
475 if symbol_name:
476 out_symbol_name = ""
477 # Look first for the inlined symbol name, otherwise use the symbol name:
478 if 'inline_symbol' in break_results and break_results['inline_symbol']:
479 out_symbol_name = break_results['inline_symbol']
480 elif 'symbol' in break_results:
481 out_symbol_name = break_results['symbol']
482
483 if symbol_match_exact:
484 test.assertTrue(symbol_name == out_symbol_name, "Symbol name '%s' doesn't match resultant symbol '%s'."%(symbol_name, out_symbol_name))
485 else:
486 test.assertTrue(out_symbol_name.find(symbol_name) != -1, "Symbol name '%s' isn't in resultant symbol '%s'."%(symbol_name, out_symbol_name))
487
488 if module_name:
Ilia K055ad9b2015-05-18 13:41:01 +0000489 out_module_name = None
Jim Ingham63dfc722012-09-22 00:05:11 +0000490 if 'module' in break_results:
491 out_module_name = break_results['module']
492
493 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))
494
495# ==================================================
Johnny Chenf4f70bb2010-10-22 21:31:03 +0000496# Utility functions related to Threads and Processes
497# ==================================================
Johnny Chen28ae2942010-10-07 22:15:58 +0000498
Johnny Chend3699082011-04-25 22:04:05 +0000499def get_stopped_threads(process, reason):
Johnny Chen75ec1592011-05-26 21:53:05 +0000500 """Returns the thread(s) with the specified stop reason in a list.
501
502 The list can be empty if no such thread exists.
503 """
Johnny Chend3699082011-04-25 22:04:05 +0000504 threads = []
Johnny Chene69c7482011-04-28 22:57:01 +0000505 for t in process:
Johnny Chend3699082011-04-25 22:04:05 +0000506 if t.GetStopReason() == reason:
507 threads.append(t)
508 return threads
509
510def get_stopped_thread(process, reason):
511 """A convenience function which returns the first thread with the given stop
512 reason or None.
513
514 Example usages:
515
516 1. Get the stopped thread due to a breakpoint condition
517
518 ...
519 from lldbutil import get_stopped_thread
Johnny Chen5a0bee72011-06-15 22:14:12 +0000520 thread = get_stopped_thread(process, lldb.eStopReasonPlanComplete)
Greg Clayton53c5ddf2013-03-19 17:59:30 +0000521 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition")
Johnny Chend3699082011-04-25 22:04:05 +0000522 ...
523
524 2. Get the thread stopped due to a breakpoint
525
526 ...
527 from lldbutil import get_stopped_thread
Johnny Chen5a0bee72011-06-15 22:14:12 +0000528 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
Greg Clayton53c5ddf2013-03-19 17:59:30 +0000529 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint")
Johnny Chend3699082011-04-25 22:04:05 +0000530 ...
531
532 """
533 threads = get_stopped_threads(process, reason)
534 if len(threads) == 0:
535 return None
536 return threads[0]
537
Johnny Chend0fef812011-04-25 23:38:13 +0000538def get_threads_stopped_at_breakpoint (process, bkpt):
539 """ For a stopped process returns the thread stopped at the breakpoint passed in bkpt"""
540 stopped_threads = []
541 threads = []
542
543 stopped_threads = get_stopped_threads (process, lldb.eStopReasonBreakpoint)
544
545 if len(stopped_threads) == 0:
546 return threads
547
548 for thread in stopped_threads:
Johnny Chen32391242011-12-22 20:21:46 +0000549 # Make sure we've hit our breakpoint...
Johnny Chend0fef812011-04-25 23:38:13 +0000550 break_id = thread.GetStopReasonDataAtIndex (0)
551 if break_id == bkpt.GetID():
552 threads.append(thread)
553
554 return threads
555
Pavel Labathc4e25c92015-05-29 10:13:03 +0000556def is_thread_crashed (test, thread):
557 """In the test suite we dereference a null pointer to simulate a crash. The way this is
558 reported depends on the platform."""
559 if test.platformIsDarwin():
560 return thread.GetStopReason() == lldb.eStopReasonException and "EXC_BAD_ACCESS" in thread.GetStopDescription(100)
561 elif test.getPlatform() == "linux":
562 return thread.GetStopReason() == lldb.eStopReasonSignal and thread.GetStopReasonDataAtIndex(0) == thread.GetProcess().GetUnixSignals().GetSignalNumberFromName("SIGSEGV")
563 else:
564 return "invalid address" in thread.GetStopDescription(100)
565
566def get_crashed_threads (test, process):
567 threads = []
568 if process.GetState() != lldb.eStateStopped:
569 return threads
570 for thread in process:
571 if is_thread_crashed(test, thread):
572 threads.append(thread)
573 return threads
574
Johnny Chend0fef812011-04-25 23:38:13 +0000575def continue_to_breakpoint (process, bkpt):
576 """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None"""
577 process.Continue()
578 if process.GetState() != lldb.eStateStopped:
579 return None
580 else:
581 return get_threads_stopped_at_breakpoint (process, bkpt)
582
Johnny Chena4603162011-03-09 23:45:56 +0000583def get_caller_symbol(thread):
584 """
585 Returns the symbol name for the call site of the leaf function.
586 """
587 depth = thread.GetNumFrames()
588 if depth <= 1:
589 return None
590 caller = thread.GetFrameAtIndex(1).GetSymbol()
591 if caller:
592 return caller.GetName()
593 else:
594 return None
595
596
Johnny Chend0fef812011-04-25 23:38:13 +0000597def get_function_names(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000598 """
599 Returns a sequence of function names from the stack frames of this thread.
600 """
601 def GetFuncName(i):
Johnny Chen4cfd07e2011-06-20 00:26:39 +0000602 return thread.GetFrameAtIndex(i).GetFunctionName()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000603
604 return map(GetFuncName, range(thread.GetNumFrames()))
605
606
Johnny Chend0fef812011-04-25 23:38:13 +0000607def get_symbol_names(thread):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000608 """
609 Returns a sequence of symbols for this thread.
610 """
611 def GetSymbol(i):
612 return thread.GetFrameAtIndex(i).GetSymbol().GetName()
613
614 return map(GetSymbol, range(thread.GetNumFrames()))
615
616
Johnny Chend0fef812011-04-25 23:38:13 +0000617def get_pc_addresses(thread):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000618 """
619 Returns a sequence of pc addresses for this thread.
620 """
621 def GetPCAddress(i):
622 return thread.GetFrameAtIndex(i).GetPCAddress()
623
624 return map(GetPCAddress, range(thread.GetNumFrames()))
625
626
Johnny Chend0fef812011-04-25 23:38:13 +0000627def get_filenames(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000628 """
629 Returns a sequence of file names from the stack frames of this thread.
630 """
631 def GetFilename(i):
632 return thread.GetFrameAtIndex(i).GetLineEntry().GetFileSpec().GetFilename()
633
634 return map(GetFilename, range(thread.GetNumFrames()))
635
636
Johnny Chend0fef812011-04-25 23:38:13 +0000637def get_line_numbers(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000638 """
639 Returns a sequence of line numbers from the stack frames of this thread.
640 """
641 def GetLineNumber(i):
642 return thread.GetFrameAtIndex(i).GetLineEntry().GetLine()
643
644 return map(GetLineNumber, range(thread.GetNumFrames()))
645
646
Johnny Chend0fef812011-04-25 23:38:13 +0000647def get_module_names(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000648 """
649 Returns a sequence of module names from the stack frames of this thread.
650 """
651 def GetModuleName(i):
652 return thread.GetFrameAtIndex(i).GetModule().GetFileSpec().GetFilename()
653
654 return map(GetModuleName, range(thread.GetNumFrames()))
655
656
Johnny Chend0fef812011-04-25 23:38:13 +0000657def get_stack_frames(thread):
Johnny Chen43a651c2010-09-09 00:55:07 +0000658 """
659 Returns a sequence of stack frames for this thread.
660 """
661 def GetStackFrame(i):
662 return thread.GetFrameAtIndex(i)
663
664 return map(GetStackFrame, range(thread.GetNumFrames()))
665
666
Johnny Chend0fef812011-04-25 23:38:13 +0000667def print_stacktrace(thread, string_buffer = False):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000668 """Prints a simple stack trace of this thread."""
Johnny Chen6c704992010-10-07 18:52:48 +0000669
Johnny Chend5d6fac2010-10-15 23:33:18 +0000670 output = StringIO.StringIO() if string_buffer else sys.stdout
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000671 target = thread.GetProcess().GetTarget()
672
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000673 depth = thread.GetNumFrames()
674
Johnny Chend0fef812011-04-25 23:38:13 +0000675 mods = get_module_names(thread)
676 funcs = get_function_names(thread)
677 symbols = get_symbol_names(thread)
678 files = get_filenames(thread)
679 lines = get_line_numbers(thread)
680 addrs = get_pc_addresses(thread)
Johnny Chen6c704992010-10-07 18:52:48 +0000681
Johnny Chen567a0452010-10-25 19:13:52 +0000682 if thread.GetStopReason() != lldb.eStopReasonInvalid:
Johnny Chende90f1d2011-04-27 17:43:07 +0000683 desc = "stop reason=" + stop_reason_to_str(thread.GetStopReason())
Johnny Chen567a0452010-10-25 19:13:52 +0000684 else:
685 desc = ""
686 print >> output, "Stack trace for thread id={0:#x} name={1} queue={2} ".format(
687 thread.GetThreadID(), thread.GetName(), thread.GetQueueName()) + desc
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000688
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000689 for i in range(depth):
690 frame = thread.GetFrameAtIndex(i)
691 function = frame.GetFunction()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000692
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000693 load_addr = addrs[i].GetLoadAddress(target)
Johnny Chen3cd1e552011-05-25 19:06:18 +0000694 if not function:
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000695 file_addr = addrs[i].GetFileAddress()
Johnny Chen0d4f6dd2011-06-16 22:07:48 +0000696 start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress()
697 symbol_offset = file_addr - start_addr
698 print >> output, " frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format(
699 num=i, addr=load_addr, mod=mods[i], symbol=symbols[i], offset=symbol_offset)
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000700 else:
Johnny Chen0d4f6dd2011-06-16 22:07:48 +0000701 print >> output, " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format(
Johnny Chen4cfd07e2011-06-20 00:26:39 +0000702 num=i, addr=load_addr, mod=mods[i],
703 func='%s [inlined]' % funcs[i] if frame.IsInlined() else funcs[i],
Johnny Chen13ea11a2011-07-13 22:34:29 +0000704 file=files[i], line=lines[i],
705 args=get_args_as_string(frame, showFuncName=False) if not frame.IsInlined() else '()')
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000706
707 if string_buffer:
Johnny Chend5d6fac2010-10-15 23:33:18 +0000708 return output.getvalue()
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000709
710
Johnny Chend0fef812011-04-25 23:38:13 +0000711def print_stacktraces(process, string_buffer = False):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000712 """Prints the stack traces of all the threads."""
713
Johnny Chend5d6fac2010-10-15 23:33:18 +0000714 output = StringIO.StringIO() if string_buffer else sys.stdout
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000715
Greg Clayton81e871e2012-02-04 02:27:34 +0000716 print >> output, "Stack traces for " + str(process)
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000717
Johnny Chenae9639a2011-05-05 18:50:56 +0000718 for thread in process:
719 print >> output, print_stacktrace(thread, string_buffer=True)
Johnny Chen6c704992010-10-07 18:52:48 +0000720
721 if string_buffer:
Johnny Chend5d6fac2010-10-15 23:33:18 +0000722 return output.getvalue()
Johnny Chenb21c52e2011-05-08 17:25:27 +0000723
724# ===================================
725# Utility functions related to Frames
726# ===================================
727
Johnny Chenad7372c2011-05-12 00:32:41 +0000728def get_parent_frame(frame):
729 """
730 Returns the parent frame of the input frame object; None if not available.
731 """
732 thread = frame.GetThread()
733 parent_found = False
734 for f in thread:
735 if parent_found:
736 return f
737 if f.GetFrameID() == frame.GetFrameID():
738 parent_found = True
739
740 # If we reach here, no parent has been found, return None.
741 return None
742
Johnny Chen0d4f6dd2011-06-16 22:07:48 +0000743def get_args_as_string(frame, showFuncName=True):
Johnny Chenad7372c2011-05-12 00:32:41 +0000744 """
745 Returns the args of the input frame object as a string.
746 """
747 # arguments => True
748 # locals => False
749 # statics => False
750 # in_scope_only => True
751 vars = frame.GetVariables(True, False, False, True) # type of SBValueList
752 args = [] # list of strings
753 for var in vars:
754 args.append("(%s)%s=%s" % (var.GetTypeName(),
755 var.GetName(),
Greg Claytonfe42ac42011-08-03 22:57:10 +0000756 var.GetValue()))
Johnny Chen3cd1e552011-05-25 19:06:18 +0000757 if frame.GetFunction():
Johnny Chen52b0ffd92011-05-13 00:44:49 +0000758 name = frame.GetFunction().GetName()
Johnny Chen3cd1e552011-05-25 19:06:18 +0000759 elif frame.GetSymbol():
Johnny Chen52b0ffd92011-05-13 00:44:49 +0000760 name = frame.GetSymbol().GetName()
761 else:
762 name = ""
Johnny Chen0d4f6dd2011-06-16 22:07:48 +0000763 if showFuncName:
764 return "%s(%s)" % (name, ", ".join(args))
765 else:
766 return "(%s)" % (", ".join(args))
767
Johnny Chenb21c52e2011-05-08 17:25:27 +0000768def print_registers(frame, string_buffer = False):
Johnny Chen2158b972011-05-08 18:55:37 +0000769 """Prints all the register sets of the frame."""
Johnny Chenb21c52e2011-05-08 17:25:27 +0000770
771 output = StringIO.StringIO() if string_buffer else sys.stdout
772
Greg Clayton81e871e2012-02-04 02:27:34 +0000773 print >> output, "Register sets for " + str(frame)
Johnny Chenb21c52e2011-05-08 17:25:27 +0000774
Johnny Chen64ff7e62011-05-10 19:21:13 +0000775 registerSet = frame.GetRegisters() # Return type of SBValueList.
776 print >> output, "Frame registers (size of register set = %d):" % registerSet.GetSize()
777 for value in registerSet:
Johnny Chenb21c52e2011-05-08 17:25:27 +0000778 #print >> output, value
779 print >> output, "%s (number of children = %d):" % (value.GetName(), value.GetNumChildren())
780 for child in value:
Greg Claytonfe42ac42011-08-03 22:57:10 +0000781 print >> output, "Name: %s, Value: %s" % (child.GetName(), child.GetValue())
Johnny Chenb21c52e2011-05-08 17:25:27 +0000782
783 if string_buffer:
784 return output.getvalue()
Johnny Chen64ff7e62011-05-10 19:21:13 +0000785
786def get_registers(frame, kind):
787 """Returns the registers given the frame and the kind of registers desired.
788
789 Returns None if there's no such kind.
790 """
791 registerSet = frame.GetRegisters() # Return type of SBValueList.
792 for value in registerSet:
793 if kind.lower() in value.GetName().lower():
794 return value
795
796 return None
797
798def get_GPRs(frame):
799 """Returns the general purpose registers of the frame as an SBValue.
800
Johnny Chene9e86892011-05-10 23:01:44 +0000801 The returned SBValue object is iterable. An example:
802 ...
803 from lldbutil import get_GPRs
804 regs = get_GPRs(frame)
805 for reg in regs:
806 print "%s => %s" % (reg.GetName(), reg.GetValue())
807 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +0000808 """
809 return get_registers(frame, "general purpose")
810
811def get_FPRs(frame):
812 """Returns the floating point registers of the frame as an SBValue.
813
Johnny Chene9e86892011-05-10 23:01:44 +0000814 The returned SBValue object is iterable. An example:
815 ...
816 from lldbutil import get_FPRs
817 regs = get_FPRs(frame)
818 for reg in regs:
819 print "%s => %s" % (reg.GetName(), reg.GetValue())
820 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +0000821 """
822 return get_registers(frame, "floating point")
823
824def get_ESRs(frame):
825 """Returns the exception state registers of the frame as an SBValue.
826
Johnny Chene9e86892011-05-10 23:01:44 +0000827 The returned SBValue object is iterable. An example:
828 ...
829 from lldbutil import get_ESRs
830 regs = get_ESRs(frame)
831 for reg in regs:
832 print "%s => %s" % (reg.GetName(), reg.GetValue())
833 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +0000834 """
835 return get_registers(frame, "exception state")
Johnny Chen989b7ef2011-07-22 00:47:58 +0000836
Johnny Chenefee1cd2011-07-22 00:51:54 +0000837# ======================================
838# Utility classes/functions for SBValues
839# ======================================
Johnny Chen989b7ef2011-07-22 00:47:58 +0000840
841class BasicFormatter(object):
Johnny Chen36d7d912011-07-22 22:01:35 +0000842 """The basic formatter inspects the value object and prints the value."""
Johnny Chen989b7ef2011-07-22 00:47:58 +0000843 def format(self, value, buffer=None, indent=0):
844 if not buffer:
845 output = StringIO.StringIO()
846 else:
847 output = buffer
Johnny Chen36d7d912011-07-22 22:01:35 +0000848 # If there is a summary, it suffices.
849 val = value.GetSummary()
850 # Otherwise, get the value.
851 if val == None:
852 val = value.GetValue()
853 if val == None and value.GetNumChildren() > 0:
854 val = "%s (location)" % value.GetLocation()
855 print >> output, "{indentation}({type}) {name} = {value}".format(
Johnny Chen989b7ef2011-07-22 00:47:58 +0000856 indentation = ' ' * indent,
857 type = value.GetTypeName(),
858 name = value.GetName(),
Johnny Chen36d7d912011-07-22 22:01:35 +0000859 value = val)
Johnny Chen989b7ef2011-07-22 00:47:58 +0000860 return output.getvalue()
861
862class ChildVisitingFormatter(BasicFormatter):
Johnny Chen36d7d912011-07-22 22:01:35 +0000863 """The child visiting formatter prints the value and its immediate children.
864
865 The constructor takes a keyword arg: indent_child, which defaults to 2.
866 """
867 def __init__(self, indent_child=2):
868 """Default indentation of 2 SPC's for the children."""
869 self.cindent = indent_child
Johnny Chen989b7ef2011-07-22 00:47:58 +0000870 def format(self, value, buffer=None):
871 if not buffer:
872 output = StringIO.StringIO()
873 else:
874 output = buffer
875
876 BasicFormatter.format(self, value, buffer=output)
877 for child in value:
Johnny Chen36d7d912011-07-22 22:01:35 +0000878 BasicFormatter.format(self, child, buffer=output, indent=self.cindent)
879
880 return output.getvalue()
881
882class RecursiveDecentFormatter(BasicFormatter):
883 """The recursive decent formatter prints the value and the decendents.
884
885 The constructor takes two keyword args: indent_level, which defaults to 0,
886 and indent_child, which defaults to 2. The current indentation level is
887 determined by indent_level, while the immediate children has an additional
888 indentation by inden_child.
889 """
890 def __init__(self, indent_level=0, indent_child=2):
891 self.lindent = indent_level
892 self.cindent = indent_child
893 def format(self, value, buffer=None):
894 if not buffer:
895 output = StringIO.StringIO()
896 else:
897 output = buffer
898
899 BasicFormatter.format(self, value, buffer=output, indent=self.lindent)
900 new_indent = self.lindent + self.cindent
901 for child in value:
902 if child.GetSummary() != None:
903 BasicFormatter.format(self, child, buffer=output, indent=new_indent)
904 else:
905 if child.GetNumChildren() > 0:
906 rdf = RecursiveDecentFormatter(indent_level=new_indent)
907 rdf.format(child, buffer=output)
908 else:
909 BasicFormatter.format(self, child, buffer=output, indent=new_indent)
Johnny Chen989b7ef2011-07-22 00:47:58 +0000910
911 return output.getvalue()
Chaoren Lin3e2bdb42015-05-11 17:53:39 +0000912
913# ===========================================================
914# Utility functions for path manipulation on remote platforms
915# ===========================================================
916
917def join_remote_paths(*paths):
918 # TODO: update with actual platform name for remote windows once it exists
919 if lldb.remote_platform.GetName() == 'remote-windows':
920 return os.path.join(*paths).replace(os.path.sep, '\\')
921 return os.path.join(*paths).replace(os.path.sep, '/')
922
923def append_to_remote_wd(*paths):
924 return join_remote_paths(lldb.remote_platform.GetWorkingDirectory(), *paths)
Chaoren Linf59d05092015-06-02 16:46:28 +0000925
926# ==================================================
927# Utility functions to get the correct signal number
928# ==================================================
929
930import signal
931
932def get_signal_number(signal_name):
933 platform = lldb.remote_platform
934 if platform:
935 if platform.GetName() == 'remote-linux':
936 command = lldb.SBPlatformShellCommand('kill -l %d' % signal_name)
937 if platform.Run(command).Success() and command.GetStatus() == 0:
938 try:
939 return int(command.GetOutput())
940 except ValueError:
941 pass
942 elif platform.GetName() == 'remote-android':
943 for signal_number in range(1, 65):
944 command = lldb.SBPlatformShellCommand('kill -l %d' % signal_number)
945 if platform.Run(command).Fail() or command.GetStatus() != 0:
946 continue
947 output = command.GetOutput().strip().upper()
948 if not output.startswith('SIG'):
949 output = 'SIG' + output
950 if output == signal_name:
951 return signal_number
952 for target_index in range(lldb.debugger.GetNumTargets()):
953 target = lldb.debugger.GetTargetAtIndex(target_index)
954 if not target.IsValid():
955 continue
956 process = target.GetProcess()
957 if not process.IsValid():
958 continue
959 signals = process.GetUnixSignals()
960 if not signals.IsValid():
961 continue
962 signal_number = signals.GetSignalNumberFromName(signal_name)
963 if signal_number > 0:
964 return signal_number
965 return getattr(signal, signal_name)