blob: a5d5f7356b198bc2eefa947a38b6f11e262bcbfb [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
Zachary Turnerff890da2015-10-19 23:45:41 +00007from __future__ import print_function
Zachary Turnerc1b7cd72015-11-05 19:22:28 +00008from __future__ import absolute_import
Zachary Turnerff890da2015-10-19 23:45:41 +00009
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000010# System modules
11import collections
12import os
Enrico Granata0b5a6e32015-09-18 20:12:52 +000013import re
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000014import sys
Johnny Chen30ee4ef2010-09-08 22:54:46 +000015
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000016# Third-party modules
Zachary Turner814236d2015-10-21 17:48:52 +000017from six import StringIO as SixStringIO
Zachary Turnercd236b82015-10-26 18:48:24 +000018import six
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000019
20# LLDB modules
21import lldb
22
Zachary Turner814236d2015-10-21 17:48:52 +000023
Johnny Chen6424b7d2011-04-26 23:07:40 +000024# ===================================================
25# Utilities for locating/checking executable programs
26# ===================================================
Johnny Chen4fdcebd2011-04-26 22:53:38 +000027
Johnny Chenac77f3b2011-03-23 20:28:59 +000028def is_exe(fpath):
Johnny Chen35ec6742011-04-26 23:10:15 +000029 """Returns True if fpath is an executable."""
Johnny Chenac77f3b2011-03-23 20:28:59 +000030 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
31
Johnny Chenac77f3b2011-03-23 20:28:59 +000032def which(program):
Johnny Chen35ec6742011-04-26 23:10:15 +000033 """Returns the full path to a program; None otherwise."""
Johnny Chenac77f3b2011-03-23 20:28:59 +000034 fpath, fname = os.path.split(program)
35 if fpath:
36 if is_exe(program):
37 return program
38 else:
39 for path in os.environ["PATH"].split(os.pathsep):
40 exe_file = os.path.join(path, program)
41 if is_exe(exe_file):
42 return exe_file
43 return None
44
Johnny Chened401982011-03-03 19:14:00 +000045# ===================================================
46# Disassembly for an SBFunction or an SBSymbol object
47# ===================================================
48
49def disassemble(target, function_or_symbol):
50 """Disassemble the function or symbol given a target.
51
52 It returns the disassembly content in a string object.
53 """
Zachary Turner814236d2015-10-21 17:48:52 +000054 buf = SixStringIO()
Johnny Chened401982011-03-03 19:14:00 +000055 insts = function_or_symbol.GetInstructions(target)
Johnny Chene69c7482011-04-28 22:57:01 +000056 for i in insts:
Zachary Turnerff890da2015-10-19 23:45:41 +000057 print(i, file=buf)
Johnny Chened401982011-03-03 19:14:00 +000058 return buf.getvalue()
59
Johnny Chen43766d62011-03-02 01:36:45 +000060# ==========================================================
61# Integer (byte size 1, 2, 4, and 8) to bytearray conversion
62# ==========================================================
63
64def int_to_bytearray(val, bytesize):
65 """Utility function to convert an integer into a bytearray.
66
Johnny Chen43e587c2011-03-02 20:54:22 +000067 It returns the bytearray in the little endian format. It is easy to get the
68 big endian format, just do ba.reverse() on the returned object.
Johnny Chen43766d62011-03-02 01:36:45 +000069 """
Johnny Chen90bb9052011-03-30 17:54:35 +000070 import struct
Johnny Chen43766d62011-03-02 01:36:45 +000071
72 if bytesize == 1:
73 return bytearray([val])
74
75 # Little endian followed by a format character.
76 template = "<%c"
77 if bytesize == 2:
78 fmt = template % 'h'
79 elif bytesize == 4:
80 fmt = template % 'i'
81 elif bytesize == 4:
82 fmt = template % 'q'
83 else:
84 return None
85
Johnny Chen90bb9052011-03-30 17:54:35 +000086 packed = struct.pack(fmt, val)
Zachary Turner1c4059a2015-10-22 20:39:59 +000087 return bytearray(list(map(ord, packed)))
Johnny Chen43766d62011-03-02 01:36:45 +000088
89def bytearray_to_int(bytes, bytesize):
90 """Utility function to convert a bytearray into an integer.
91
Johnny Chen43e587c2011-03-02 20:54:22 +000092 It interprets the bytearray in the little endian format. For a big endian
93 bytearray, just do ba.reverse() on the object before passing it in.
Johnny Chen43766d62011-03-02 01:36:45 +000094 """
Johnny Chen90bb9052011-03-30 17:54:35 +000095 import struct
Johnny Chen43766d62011-03-02 01:36:45 +000096
97 if bytesize == 1:
Filipe Cabecinhas5d261b02012-07-06 16:20:13 +000098 return bytes[0]
Johnny Chen43766d62011-03-02 01:36:45 +000099
100 # Little endian followed by a format character.
101 template = "<%c"
102 if bytesize == 2:
103 fmt = template % 'h'
104 elif bytesize == 4:
105 fmt = template % 'i'
106 elif bytesize == 4:
107 fmt = template % 'q'
108 else:
109 return None
110
Johnny Chen90bb9052011-03-30 17:54:35 +0000111 unpacked = struct.unpack(fmt, str(bytes))
Johnny Chen43766d62011-03-02 01:36:45 +0000112 return unpacked[0]
113
114
Johnny Chen90256cd2011-04-23 00:13:34 +0000115# ==============================================================
116# Get the description of an lldb object or None if not available
117# ==============================================================
Johnny Chenfc87e2d2011-04-25 20:23:05 +0000118def get_description(obj, option=None):
119 """Calls lldb_obj.GetDescription() and returns a string, or None.
120
Johnny Chen01a67862011-10-14 00:42:25 +0000121 For SBTarget, SBBreakpointLocation, and SBWatchpoint lldb objects, an extra
122 option can be passed in to describe the detailed level of description
123 desired:
Johnny Chenfc87e2d2011-04-25 20:23:05 +0000124 o lldb.eDescriptionLevelBrief
125 o lldb.eDescriptionLevelFull
126 o lldb.eDescriptionLevelVerbose
127 """
128 method = getattr(obj, 'GetDescription')
Johnny Chen90256cd2011-04-23 00:13:34 +0000129 if not method:
130 return None
Johnny Chen01a67862011-10-14 00:42:25 +0000131 tuple = (lldb.SBTarget, lldb.SBBreakpointLocation, lldb.SBWatchpoint)
Johnny Chen469683e2011-09-27 21:27:19 +0000132 if isinstance(obj, tuple):
Johnny Chenfc87e2d2011-04-25 20:23:05 +0000133 if option is None:
134 option = lldb.eDescriptionLevelBrief
135
Johnny Chen90256cd2011-04-23 00:13:34 +0000136 stream = lldb.SBStream()
137 if option is None:
138 success = method(stream)
139 else:
140 success = method(stream, option)
141 if not success:
142 return None
143 return stream.GetData()
144
145
Johnny Chenf4f70bb2010-10-22 21:31:03 +0000146# =================================================
147# Convert some enum value to its string counterpart
148# =================================================
Johnny Chen28ae2942010-10-07 22:15:58 +0000149
Johnny Chende90f1d2011-04-27 17:43:07 +0000150def state_type_to_str(enum):
Johnny Chen28ae2942010-10-07 22:15:58 +0000151 """Returns the stateType string given an enum."""
152 if enum == lldb.eStateInvalid:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000153 return "invalid"
Johnny Chen28ae2942010-10-07 22:15:58 +0000154 elif enum == lldb.eStateUnloaded:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000155 return "unloaded"
Johnny Chen930e3ad2011-03-05 01:20:11 +0000156 elif enum == lldb.eStateConnected:
157 return "connected"
Johnny Chen28ae2942010-10-07 22:15:58 +0000158 elif enum == lldb.eStateAttaching:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000159 return "attaching"
Johnny Chen28ae2942010-10-07 22:15:58 +0000160 elif enum == lldb.eStateLaunching:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000161 return "launching"
Johnny Chen28ae2942010-10-07 22:15:58 +0000162 elif enum == lldb.eStateStopped:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000163 return "stopped"
Johnny Chen28ae2942010-10-07 22:15:58 +0000164 elif enum == lldb.eStateRunning:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000165 return "running"
Johnny Chen28ae2942010-10-07 22:15:58 +0000166 elif enum == lldb.eStateStepping:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000167 return "stepping"
Johnny Chen28ae2942010-10-07 22:15:58 +0000168 elif enum == lldb.eStateCrashed:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000169 return "crashed"
Johnny Chen28ae2942010-10-07 22:15:58 +0000170 elif enum == lldb.eStateDetached:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000171 return "detached"
Johnny Chen28ae2942010-10-07 22:15:58 +0000172 elif enum == lldb.eStateExited:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000173 return "exited"
Johnny Chen28ae2942010-10-07 22:15:58 +0000174 elif enum == lldb.eStateSuspended:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000175 return "suspended"
Johnny Chen28ae2942010-10-07 22:15:58 +0000176 else:
Johnny Chen930e3ad2011-03-05 01:20:11 +0000177 raise Exception("Unknown StateType enum")
Johnny Chen28ae2942010-10-07 22:15:58 +0000178
Johnny Chende90f1d2011-04-27 17:43:07 +0000179def stop_reason_to_str(enum):
Johnny Chen28ae2942010-10-07 22:15:58 +0000180 """Returns the stopReason string given an enum."""
181 if enum == lldb.eStopReasonInvalid:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000182 return "invalid"
Johnny Chen28ae2942010-10-07 22:15:58 +0000183 elif enum == lldb.eStopReasonNone:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000184 return "none"
Johnny Chen28ae2942010-10-07 22:15:58 +0000185 elif enum == lldb.eStopReasonTrace:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000186 return "trace"
Johnny Chen28ae2942010-10-07 22:15:58 +0000187 elif enum == lldb.eStopReasonBreakpoint:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000188 return "breakpoint"
Johnny Chen28ae2942010-10-07 22:15:58 +0000189 elif enum == lldb.eStopReasonWatchpoint:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000190 return "watchpoint"
Jim Ingham6cc0d2f2014-04-03 01:25:28 +0000191 elif enum == lldb.eStopReasonExec:
192 return "exec"
Johnny Chen28ae2942010-10-07 22:15:58 +0000193 elif enum == lldb.eStopReasonSignal:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000194 return "signal"
Johnny Chen28ae2942010-10-07 22:15:58 +0000195 elif enum == lldb.eStopReasonException:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000196 return "exception"
Johnny Chen28ae2942010-10-07 22:15:58 +0000197 elif enum == lldb.eStopReasonPlanComplete:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000198 return "plancomplete"
Daniel Maleab3d41a22013-07-09 00:08:01 +0000199 elif enum == lldb.eStopReasonThreadExiting:
200 return "threadexiting"
Johnny Chen28ae2942010-10-07 22:15:58 +0000201 else:
Johnny Chen930e3ad2011-03-05 01:20:11 +0000202 raise Exception("Unknown StopReason enum")
Johnny Chen28ae2942010-10-07 22:15:58 +0000203
Johnny Chena32a13d2011-09-28 00:51:00 +0000204def symbol_type_to_str(enum):
205 """Returns the symbolType string given an enum."""
206 if enum == lldb.eSymbolTypeInvalid:
207 return "invalid"
208 elif enum == lldb.eSymbolTypeAbsolute:
209 return "absolute"
Johnny Chena32a13d2011-09-28 00:51:00 +0000210 elif enum == lldb.eSymbolTypeCode:
211 return "code"
212 elif enum == lldb.eSymbolTypeData:
213 return "data"
214 elif enum == lldb.eSymbolTypeTrampoline:
215 return "trampoline"
216 elif enum == lldb.eSymbolTypeRuntime:
217 return "runtime"
218 elif enum == lldb.eSymbolTypeException:
219 return "exception"
220 elif enum == lldb.eSymbolTypeSourceFile:
221 return "sourcefile"
222 elif enum == lldb.eSymbolTypeHeaderFile:
223 return "headerfile"
224 elif enum == lldb.eSymbolTypeObjectFile:
225 return "objectfile"
226 elif enum == lldb.eSymbolTypeCommonBlock:
227 return "commonblock"
228 elif enum == lldb.eSymbolTypeBlock:
229 return "block"
230 elif enum == lldb.eSymbolTypeLocal:
231 return "local"
232 elif enum == lldb.eSymbolTypeParam:
233 return "param"
234 elif enum == lldb.eSymbolTypeVariable:
235 return "variable"
236 elif enum == lldb.eSymbolTypeVariableType:
237 return "variabletype"
238 elif enum == lldb.eSymbolTypeLineEntry:
239 return "lineentry"
240 elif enum == lldb.eSymbolTypeLineHeader:
241 return "lineheader"
242 elif enum == lldb.eSymbolTypeScopeBegin:
243 return "scopebegin"
244 elif enum == lldb.eSymbolTypeScopeEnd:
245 return "scopeend"
246 elif enum == lldb.eSymbolTypeAdditional:
247 return "additional"
248 elif enum == lldb.eSymbolTypeCompiler:
249 return "compiler"
250 elif enum == lldb.eSymbolTypeInstrumentation:
251 return "instrumentation"
252 elif enum == lldb.eSymbolTypeUndefined:
253 return "undefined"
254
Johnny Chende90f1d2011-04-27 17:43:07 +0000255def value_type_to_str(enum):
Johnny Chen87bb5892010-11-03 21:37:58 +0000256 """Returns the valueType string given an enum."""
257 if enum == lldb.eValueTypeInvalid:
258 return "invalid"
259 elif enum == lldb.eValueTypeVariableGlobal:
260 return "global_variable"
261 elif enum == lldb.eValueTypeVariableStatic:
262 return "static_variable"
263 elif enum == lldb.eValueTypeVariableArgument:
264 return "argument_variable"
265 elif enum == lldb.eValueTypeVariableLocal:
266 return "local_variable"
267 elif enum == lldb.eValueTypeRegister:
268 return "register"
269 elif enum == lldb.eValueTypeRegisterSet:
270 return "register_set"
271 elif enum == lldb.eValueTypeConstResult:
272 return "constant_result"
273 else:
Johnny Chen930e3ad2011-03-05 01:20:11 +0000274 raise Exception("Unknown ValueType enum")
Johnny Chen87bb5892010-11-03 21:37:58 +0000275
Johnny Chen28ae2942010-10-07 22:15:58 +0000276
Johnny Chenf4f70bb2010-10-22 21:31:03 +0000277# ==================================================
Daniel Maleab3d41a22013-07-09 00:08:01 +0000278# Get stopped threads due to each stop reason.
279# ==================================================
280
281def sort_stopped_threads(process,
282 breakpoint_threads = None,
283 crashed_threads = None,
284 watchpoint_threads = None,
285 signal_threads = None,
286 exiting_threads = None,
287 other_threads = None):
288 """ Fills array *_threads with threads stopped for the corresponding stop
289 reason.
290 """
291 for lst in [breakpoint_threads,
292 watchpoint_threads,
293 signal_threads,
294 exiting_threads,
295 other_threads]:
296 if lst is not None:
297 lst[:] = []
298
299 for thread in process:
300 dispatched = False
301 for (reason, list) in [(lldb.eStopReasonBreakpoint, breakpoint_threads),
302 (lldb.eStopReasonException, crashed_threads),
303 (lldb.eStopReasonWatchpoint, watchpoint_threads),
304 (lldb.eStopReasonSignal, signal_threads),
305 (lldb.eStopReasonThreadExiting, exiting_threads),
306 (None, other_threads)]:
307 if not dispatched and list is not None:
308 if thread.GetStopReason() == reason or reason is None:
309 list.append(thread)
310 dispatched = True
311
312# ==================================================
Jim Ingham63dfc722012-09-22 00:05:11 +0000313# Utility functions for setting breakpoints
314# ==================================================
315
316def 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):
317 """Set a breakpoint by file and line, returning the breakpoint number.
318
319 If extra_options is not None, then we append it to the breakpoint set command.
320
321 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.
322
323 If loc_exact is true, we check that there is one location, and that location must be at the input file and line number."""
324
325 if file_name == None:
326 command = 'breakpoint set -l %d'%(line_number)
327 else:
328 command = 'breakpoint set -f "%s" -l %d'%(file_name, line_number)
329
Greg Claytonc1b2ccf2013-01-08 00:01:36 +0000330 if module_name:
331 command += " --shlib '%s'" % (module_name)
332
Jim Ingham63dfc722012-09-22 00:05:11 +0000333 if extra_options:
334 command += " " + extra_options
335
336 break_results = run_break_set_command (test, command)
337
338 if num_expected_locations == 1 and loc_exact:
339 check_breakpoint_result (test, break_results, num_locations=num_expected_locations, file_name = file_name, line_number = line_number, module_name=module_name)
340 else:
341 check_breakpoint_result (test, break_results, num_locations = num_expected_locations)
342
343 return get_bpno_from_match (break_results)
344
345def run_break_set_by_symbol (test, symbol, extra_options = None, num_expected_locations = -1, sym_exact = False, module_name=None):
346 """Set a breakpoint by symbol name. Common options are the same as run_break_set_by_file_and_line.
347
348 If sym_exact is true, then the output symbol must match the input exactly, otherwise we do a substring match."""
349 command = 'breakpoint set -n "%s"'%(symbol)
Greg Claytonc1b2ccf2013-01-08 00:01:36 +0000350
351 if module_name:
352 command += " --shlib '%s'" % (module_name)
353
Jim Ingham63dfc722012-09-22 00:05:11 +0000354 if extra_options:
355 command += " " + extra_options
356
357 break_results = run_break_set_command (test, command)
358
359 if num_expected_locations == 1 and sym_exact:
360 check_breakpoint_result (test, break_results, num_locations = num_expected_locations, symbol_name = symbol, module_name=module_name)
361 else:
362 check_breakpoint_result (test, break_results, num_locations = num_expected_locations)
363
364 return get_bpno_from_match (break_results)
365
366def run_break_set_by_selector (test, selector, extra_options = None, num_expected_locations = -1, module_name=None):
367 """Set a breakpoint by selector. Common options are the same as run_break_set_by_file_and_line."""
368
Greg Claytonc1b2ccf2013-01-08 00:01:36 +0000369 command = 'breakpoint set -S "%s"' % (selector)
370
371 if module_name:
372 command += ' --shlib "%s"' % (module_name)
373
Jim Ingham63dfc722012-09-22 00:05:11 +0000374 if extra_options:
375 command += " " + extra_options
376
377 break_results = run_break_set_command (test, command)
378
379 if num_expected_locations == 1:
380 check_breakpoint_result (test, break_results, num_locations = num_expected_locations, symbol_name = selector, symbol_match_exact=False, module_name=module_name)
381 else:
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_regexp (test, regexp, extra_options=None, num_expected_locations=-1):
387 """Set a breakpoint by regular expression match on symbol name. Common options are the same as run_break_set_by_file_and_line."""
388
389 command = 'breakpoint set -r "%s"'%(regexp)
390 if extra_options:
391 command += " " + extra_options
392
393 break_results = run_break_set_command (test, command)
394
395 check_breakpoint_result (test, break_results, num_locations=num_expected_locations)
396
397 return get_bpno_from_match (break_results)
398
399def run_break_set_by_source_regexp (test, regexp, extra_options=None, num_expected_locations=-1):
400 """Set a breakpoint by source regular expression. Common options are the same as run_break_set_by_file_and_line."""
401 command = 'breakpoint set -p "%s"'%(regexp)
402 if extra_options:
403 command += " " + extra_options
404
405 break_results = run_break_set_command (test, command)
406
407 check_breakpoint_result (test, break_results, num_locations=num_expected_locations)
408
409 return get_bpno_from_match (break_results)
410
411def run_break_set_command (test, command):
412 """Run the command passed in - it must be some break set variant - and analyze the result.
413 Returns a dictionary of information gleaned from the command-line results.
414 Will assert if the breakpoint setting fails altogether.
415
416 Dictionary will contain:
417 bpno - breakpoint of the newly created breakpoint, -1 on error.
418 num_locations - number of locations set for the breakpoint.
419
420 If there is only one location, the dictionary MAY contain:
421 file - source file name
422 line_no - source line number
423 symbol - symbol name
424 inline_symbol - inlined symbol name
425 offset - offset from the original symbol
426 module - module
427 address - address at which the breakpoint was set."""
428
429 patterns = [r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>[0-9]+) locations\.$",
430 r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>no) locations \(pending\)\.",
431 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]+)$",
432 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]+)$"]
433 match_object = test.match (command, patterns)
434 break_results = match_object.groupdict()
Jim Ingham63dfc722012-09-22 00:05:11 +0000435
436 # We always insert the breakpoint number, setting it to -1 if we couldn't find it
437 # Also, make sure it gets stored as an integer.
438 if not 'bpno' in break_results:
439 break_results['bpno'] = -1
440 else:
441 break_results['bpno'] = int(break_results['bpno'])
442
443 # We always insert the number of locations
444 # If ONE location is set for the breakpoint, then the output doesn't mention locations, but it has to be 1...
445 # We also make sure it is an integer.
446
447 if not 'num_locations' in break_results:
448 num_locations = 1
449 else:
450 num_locations = break_results['num_locations']
451 if num_locations == 'no':
452 num_locations = 0
453 else:
454 num_locations = int(break_results['num_locations'])
455
456 break_results['num_locations'] = num_locations
457
458 if 'line_no' in break_results:
459 break_results['line_no'] = int(break_results['line_no'])
460
461 return break_results
462
463def get_bpno_from_match (break_results):
464 return int (break_results['bpno'])
465
466def 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):
467
468 out_num_locations = break_results['num_locations']
469
Jim Ingham63dfc722012-09-22 00:05:11 +0000470 if num_locations == -1:
471 test.assertTrue (out_num_locations > 0, "Expecting one or more locations, got none.")
472 else:
473 test.assertTrue (num_locations == out_num_locations, "Expecting %d locations, got %d."%(num_locations, out_num_locations))
474
475 if file_name:
476 out_file_name = ""
477 if 'file' in break_results:
478 out_file_name = break_results['file']
479 test.assertTrue (file_name == out_file_name, "Breakpoint file name '%s' doesn't match resultant name '%s'."%(file_name, out_file_name))
480
481 if line_number != -1:
Ilia K055ad9b2015-05-18 13:41:01 +0000482 out_line_number = -1
Jim Ingham63dfc722012-09-22 00:05:11 +0000483 if 'line_no' in break_results:
484 out_line_number = break_results['line_no']
485
486 test.assertTrue (line_number == out_line_number, "Breakpoint line number %s doesn't match resultant line %s."%(line_number, out_line_number))
487
488 if symbol_name:
489 out_symbol_name = ""
490 # Look first for the inlined symbol name, otherwise use the symbol name:
491 if 'inline_symbol' in break_results and break_results['inline_symbol']:
492 out_symbol_name = break_results['inline_symbol']
493 elif 'symbol' in break_results:
494 out_symbol_name = break_results['symbol']
495
496 if symbol_match_exact:
497 test.assertTrue(symbol_name == out_symbol_name, "Symbol name '%s' doesn't match resultant symbol '%s'."%(symbol_name, out_symbol_name))
498 else:
499 test.assertTrue(out_symbol_name.find(symbol_name) != -1, "Symbol name '%s' isn't in resultant symbol '%s'."%(symbol_name, out_symbol_name))
500
501 if module_name:
Ilia K055ad9b2015-05-18 13:41:01 +0000502 out_module_name = None
Jim Ingham63dfc722012-09-22 00:05:11 +0000503 if 'module' in break_results:
504 out_module_name = break_results['module']
505
506 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))
507
508# ==================================================
Johnny Chenf4f70bb2010-10-22 21:31:03 +0000509# Utility functions related to Threads and Processes
510# ==================================================
Johnny Chen28ae2942010-10-07 22:15:58 +0000511
Johnny Chend3699082011-04-25 22:04:05 +0000512def get_stopped_threads(process, reason):
Johnny Chen75ec1592011-05-26 21:53:05 +0000513 """Returns the thread(s) with the specified stop reason in a list.
514
515 The list can be empty if no such thread exists.
516 """
Johnny Chend3699082011-04-25 22:04:05 +0000517 threads = []
Johnny Chene69c7482011-04-28 22:57:01 +0000518 for t in process:
Johnny Chend3699082011-04-25 22:04:05 +0000519 if t.GetStopReason() == reason:
520 threads.append(t)
521 return threads
522
523def get_stopped_thread(process, reason):
524 """A convenience function which returns the first thread with the given stop
525 reason or None.
526
527 Example usages:
528
529 1. Get the stopped thread due to a breakpoint condition
530
531 ...
532 from lldbutil import get_stopped_thread
Johnny Chen5a0bee72011-06-15 22:14:12 +0000533 thread = get_stopped_thread(process, lldb.eStopReasonPlanComplete)
Greg Clayton53c5ddf2013-03-19 17:59:30 +0000534 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition")
Johnny Chend3699082011-04-25 22:04:05 +0000535 ...
536
537 2. Get the thread stopped due to a breakpoint
538
539 ...
540 from lldbutil import get_stopped_thread
Johnny Chen5a0bee72011-06-15 22:14:12 +0000541 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
Greg Clayton53c5ddf2013-03-19 17:59:30 +0000542 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint")
Johnny Chend3699082011-04-25 22:04:05 +0000543 ...
544
545 """
546 threads = get_stopped_threads(process, reason)
547 if len(threads) == 0:
548 return None
549 return threads[0]
550
Johnny Chend0fef812011-04-25 23:38:13 +0000551def get_threads_stopped_at_breakpoint (process, bkpt):
552 """ For a stopped process returns the thread stopped at the breakpoint passed in bkpt"""
553 stopped_threads = []
554 threads = []
555
556 stopped_threads = get_stopped_threads (process, lldb.eStopReasonBreakpoint)
557
558 if len(stopped_threads) == 0:
559 return threads
560
561 for thread in stopped_threads:
Johnny Chen32391242011-12-22 20:21:46 +0000562 # Make sure we've hit our breakpoint...
Johnny Chend0fef812011-04-25 23:38:13 +0000563 break_id = thread.GetStopReasonDataAtIndex (0)
564 if break_id == bkpt.GetID():
565 threads.append(thread)
566
567 return threads
568
Zachary Turner783550b2016-01-21 21:07:30 +0000569def get_one_thread_stopped_at_breakpoint(process, bkpt, require_exactly_one = True):
570 threads = get_threads_stopped_at_breakpoint(process, bkpt)
571 if len(threads) == 0:
572 return None
573 if require_exactly_one and len(threads) != 1:
574 return None
575
576 return threads[0]
577
Pavel Labathc4e25c92015-05-29 10:13:03 +0000578def is_thread_crashed (test, thread):
579 """In the test suite we dereference a null pointer to simulate a crash. The way this is
580 reported depends on the platform."""
581 if test.platformIsDarwin():
582 return thread.GetStopReason() == lldb.eStopReasonException and "EXC_BAD_ACCESS" in thread.GetStopDescription(100)
583 elif test.getPlatform() == "linux":
584 return thread.GetStopReason() == lldb.eStopReasonSignal and thread.GetStopReasonDataAtIndex(0) == thread.GetProcess().GetUnixSignals().GetSignalNumberFromName("SIGSEGV")
585 else:
586 return "invalid address" in thread.GetStopDescription(100)
587
588def get_crashed_threads (test, process):
589 threads = []
590 if process.GetState() != lldb.eStateStopped:
591 return threads
592 for thread in process:
593 if is_thread_crashed(test, thread):
594 threads.append(thread)
595 return threads
596
Johnny Chend0fef812011-04-25 23:38:13 +0000597def continue_to_breakpoint (process, bkpt):
598 """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None"""
599 process.Continue()
600 if process.GetState() != lldb.eStateStopped:
601 return None
602 else:
603 return get_threads_stopped_at_breakpoint (process, bkpt)
604
Johnny Chena4603162011-03-09 23:45:56 +0000605def get_caller_symbol(thread):
606 """
607 Returns the symbol name for the call site of the leaf function.
608 """
609 depth = thread.GetNumFrames()
610 if depth <= 1:
611 return None
612 caller = thread.GetFrameAtIndex(1).GetSymbol()
613 if caller:
614 return caller.GetName()
615 else:
616 return None
617
618
Johnny Chend0fef812011-04-25 23:38:13 +0000619def get_function_names(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000620 """
621 Returns a sequence of function names from the stack frames of this thread.
622 """
623 def GetFuncName(i):
Johnny Chen4cfd07e2011-06-20 00:26:39 +0000624 return thread.GetFrameAtIndex(i).GetFunctionName()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000625
Zachary Turner744cd5d2015-10-26 16:49:57 +0000626 return list(map(GetFuncName, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000627
628
Johnny Chend0fef812011-04-25 23:38:13 +0000629def get_symbol_names(thread):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000630 """
631 Returns a sequence of symbols for this thread.
632 """
633 def GetSymbol(i):
634 return thread.GetFrameAtIndex(i).GetSymbol().GetName()
635
Zachary Turner744cd5d2015-10-26 16:49:57 +0000636 return list(map(GetSymbol, list(range(thread.GetNumFrames()))))
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000637
638
Johnny Chend0fef812011-04-25 23:38:13 +0000639def get_pc_addresses(thread):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000640 """
641 Returns a sequence of pc addresses for this thread.
642 """
643 def GetPCAddress(i):
644 return thread.GetFrameAtIndex(i).GetPCAddress()
645
Zachary Turner744cd5d2015-10-26 16:49:57 +0000646 return list(map(GetPCAddress, list(range(thread.GetNumFrames()))))
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000647
648
Johnny Chend0fef812011-04-25 23:38:13 +0000649def get_filenames(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000650 """
651 Returns a sequence of file names from the stack frames of this thread.
652 """
653 def GetFilename(i):
654 return thread.GetFrameAtIndex(i).GetLineEntry().GetFileSpec().GetFilename()
655
Zachary Turner744cd5d2015-10-26 16:49:57 +0000656 return list(map(GetFilename, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000657
658
Johnny Chend0fef812011-04-25 23:38:13 +0000659def get_line_numbers(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000660 """
661 Returns a sequence of line numbers from the stack frames of this thread.
662 """
663 def GetLineNumber(i):
664 return thread.GetFrameAtIndex(i).GetLineEntry().GetLine()
665
Zachary Turner744cd5d2015-10-26 16:49:57 +0000666 return list(map(GetLineNumber, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000667
668
Johnny Chend0fef812011-04-25 23:38:13 +0000669def get_module_names(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000670 """
671 Returns a sequence of module names from the stack frames of this thread.
672 """
673 def GetModuleName(i):
674 return thread.GetFrameAtIndex(i).GetModule().GetFileSpec().GetFilename()
675
Zachary Turner744cd5d2015-10-26 16:49:57 +0000676 return list(map(GetModuleName, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000677
678
Johnny Chend0fef812011-04-25 23:38:13 +0000679def get_stack_frames(thread):
Johnny Chen43a651c2010-09-09 00:55:07 +0000680 """
681 Returns a sequence of stack frames for this thread.
682 """
683 def GetStackFrame(i):
684 return thread.GetFrameAtIndex(i)
685
Zachary Turner744cd5d2015-10-26 16:49:57 +0000686 return list(map(GetStackFrame, list(range(thread.GetNumFrames()))))
Johnny Chen43a651c2010-09-09 00:55:07 +0000687
688
Johnny Chend0fef812011-04-25 23:38:13 +0000689def print_stacktrace(thread, string_buffer = False):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000690 """Prints a simple stack trace of this thread."""
Johnny Chen6c704992010-10-07 18:52:48 +0000691
Zachary Turner814236d2015-10-21 17:48:52 +0000692 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000693 target = thread.GetProcess().GetTarget()
694
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000695 depth = thread.GetNumFrames()
696
Johnny Chend0fef812011-04-25 23:38:13 +0000697 mods = get_module_names(thread)
698 funcs = get_function_names(thread)
699 symbols = get_symbol_names(thread)
700 files = get_filenames(thread)
701 lines = get_line_numbers(thread)
702 addrs = get_pc_addresses(thread)
Johnny Chen6c704992010-10-07 18:52:48 +0000703
Johnny Chen567a0452010-10-25 19:13:52 +0000704 if thread.GetStopReason() != lldb.eStopReasonInvalid:
Johnny Chende90f1d2011-04-27 17:43:07 +0000705 desc = "stop reason=" + stop_reason_to_str(thread.GetStopReason())
Johnny Chen567a0452010-10-25 19:13:52 +0000706 else:
707 desc = ""
Zachary Turnerff890da2015-10-19 23:45:41 +0000708 print("Stack trace for thread id={0:#x} name={1} queue={2} ".format(
709 thread.GetThreadID(), thread.GetName(), thread.GetQueueName()) + desc, file=output)
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000710
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000711 for i in range(depth):
712 frame = thread.GetFrameAtIndex(i)
713 function = frame.GetFunction()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000714
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000715 load_addr = addrs[i].GetLoadAddress(target)
Johnny Chen3cd1e552011-05-25 19:06:18 +0000716 if not function:
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000717 file_addr = addrs[i].GetFileAddress()
Johnny Chen0d4f6dd2011-06-16 22:07:48 +0000718 start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress()
719 symbol_offset = file_addr - start_addr
Zachary Turnerff890da2015-10-19 23:45:41 +0000720 print(" frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format(
721 num=i, addr=load_addr, mod=mods[i], symbol=symbols[i], offset=symbol_offset), file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000722 else:
Zachary Turnerff890da2015-10-19 23:45:41 +0000723 print(" frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format(
Johnny Chen4cfd07e2011-06-20 00:26:39 +0000724 num=i, addr=load_addr, mod=mods[i],
725 func='%s [inlined]' % funcs[i] if frame.IsInlined() else funcs[i],
Johnny Chen13ea11a2011-07-13 22:34:29 +0000726 file=files[i], line=lines[i],
Zachary Turnerff890da2015-10-19 23:45:41 +0000727 args=get_args_as_string(frame, showFuncName=False) if not frame.IsInlined() else '()'), file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000728
729 if string_buffer:
Johnny Chend5d6fac2010-10-15 23:33:18 +0000730 return output.getvalue()
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000731
732
Johnny Chend0fef812011-04-25 23:38:13 +0000733def print_stacktraces(process, string_buffer = False):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000734 """Prints the stack traces of all the threads."""
735
Zachary Turner814236d2015-10-21 17:48:52 +0000736 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000737
Zachary Turnerff890da2015-10-19 23:45:41 +0000738 print("Stack traces for " + str(process), file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000739
Johnny Chenae9639a2011-05-05 18:50:56 +0000740 for thread in process:
Zachary Turnerff890da2015-10-19 23:45:41 +0000741 print(print_stacktrace(thread, string_buffer=True), file=output)
Johnny Chen6c704992010-10-07 18:52:48 +0000742
743 if string_buffer:
Johnny Chend5d6fac2010-10-15 23:33:18 +0000744 return output.getvalue()
Johnny Chenb21c52e2011-05-08 17:25:27 +0000745
Pavel Labath5dcb0252015-09-02 09:12:28 +0000746def expect_state_changes(test, listener, states, timeout = 5):
747 """Listens for state changed events on the listener and makes sure they match what we
748 expect. Stop-and-restart events (where GetRestartedFromEvent() returns true) are ignored."""
Pavel Labathe5c98082016-01-06 11:40:06 +0000749
Pavel Labath5dcb0252015-09-02 09:12:28 +0000750 for expected_state in states:
Pavel Labathe5c98082016-01-06 11:40:06 +0000751 def get_next_event():
752 event = lldb.SBEvent()
753 if not listener.WaitForEvent(timeout, event):
754 test.fail("Timed out while waiting for a transition to state %s" %
755 lldb.SBDebugger.StateAsCString(expected_state))
756 return event
Pavel Labath5dcb0252015-09-02 09:12:28 +0000757
Pavel Labathe5c98082016-01-06 11:40:06 +0000758 event = get_next_event()
759 while (lldb.SBProcess.GetStateFromEvent(event) == lldb.eStateStopped and
760 lldb.SBProcess.GetRestartedFromEvent(event)):
761 # Ignore restarted event and the subsequent running event.
762 event = get_next_event()
763 test.assertEqual(lldb.SBProcess.GetStateFromEvent(event), lldb.eStateRunning,
764 "Restarted event followed by a running event")
765 event = get_next_event()
Pavel Labath5dcb0252015-09-02 09:12:28 +0000766
Pavel Labathe5c98082016-01-06 11:40:06 +0000767 test.assertEqual(lldb.SBProcess.GetStateFromEvent(event), expected_state)
Pavel Labath5dcb0252015-09-02 09:12:28 +0000768
Johnny Chenb21c52e2011-05-08 17:25:27 +0000769# ===================================
770# Utility functions related to Frames
771# ===================================
772
Johnny Chenad7372c2011-05-12 00:32:41 +0000773def get_parent_frame(frame):
774 """
775 Returns the parent frame of the input frame object; None if not available.
776 """
777 thread = frame.GetThread()
778 parent_found = False
779 for f in thread:
780 if parent_found:
781 return f
782 if f.GetFrameID() == frame.GetFrameID():
783 parent_found = True
784
785 # If we reach here, no parent has been found, return None.
786 return None
787
Johnny Chen0d4f6dd2011-06-16 22:07:48 +0000788def get_args_as_string(frame, showFuncName=True):
Johnny Chenad7372c2011-05-12 00:32:41 +0000789 """
790 Returns the args of the input frame object as a string.
791 """
792 # arguments => True
793 # locals => False
794 # statics => False
795 # in_scope_only => True
796 vars = frame.GetVariables(True, False, False, True) # type of SBValueList
797 args = [] # list of strings
798 for var in vars:
799 args.append("(%s)%s=%s" % (var.GetTypeName(),
800 var.GetName(),
Greg Claytonfe42ac42011-08-03 22:57:10 +0000801 var.GetValue()))
Johnny Chen3cd1e552011-05-25 19:06:18 +0000802 if frame.GetFunction():
Johnny Chen52b0ffd92011-05-13 00:44:49 +0000803 name = frame.GetFunction().GetName()
Johnny Chen3cd1e552011-05-25 19:06:18 +0000804 elif frame.GetSymbol():
Johnny Chen52b0ffd92011-05-13 00:44:49 +0000805 name = frame.GetSymbol().GetName()
806 else:
807 name = ""
Johnny Chen0d4f6dd2011-06-16 22:07:48 +0000808 if showFuncName:
809 return "%s(%s)" % (name, ", ".join(args))
810 else:
811 return "(%s)" % (", ".join(args))
812
Johnny Chenb21c52e2011-05-08 17:25:27 +0000813def print_registers(frame, string_buffer = False):
Johnny Chen2158b972011-05-08 18:55:37 +0000814 """Prints all the register sets of the frame."""
Johnny Chenb21c52e2011-05-08 17:25:27 +0000815
Zachary Turner814236d2015-10-21 17:48:52 +0000816 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chenb21c52e2011-05-08 17:25:27 +0000817
Zachary Turnerff890da2015-10-19 23:45:41 +0000818 print("Register sets for " + str(frame), file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +0000819
Johnny Chen64ff7e62011-05-10 19:21:13 +0000820 registerSet = frame.GetRegisters() # Return type of SBValueList.
Zachary Turnerff890da2015-10-19 23:45:41 +0000821 print("Frame registers (size of register set = %d):" % registerSet.GetSize(), file=output)
Johnny Chen64ff7e62011-05-10 19:21:13 +0000822 for value in registerSet:
Zachary Turner35d017f2015-10-23 17:04:29 +0000823 #print(value, file=output)
Zachary Turnerff890da2015-10-19 23:45:41 +0000824 print("%s (number of children = %d):" % (value.GetName(), value.GetNumChildren()), file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +0000825 for child in value:
Zachary Turnerff890da2015-10-19 23:45:41 +0000826 print("Name: %s, Value: %s" % (child.GetName(), child.GetValue()), file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +0000827
828 if string_buffer:
829 return output.getvalue()
Johnny Chen64ff7e62011-05-10 19:21:13 +0000830
831def get_registers(frame, kind):
832 """Returns the registers given the frame and the kind of registers desired.
833
834 Returns None if there's no such kind.
835 """
836 registerSet = frame.GetRegisters() # Return type of SBValueList.
837 for value in registerSet:
838 if kind.lower() in value.GetName().lower():
839 return value
840
841 return None
842
843def get_GPRs(frame):
844 """Returns the general purpose registers of the frame as an SBValue.
845
Johnny Chene9e86892011-05-10 23:01:44 +0000846 The returned SBValue object is iterable. An example:
847 ...
848 from lldbutil import get_GPRs
849 regs = get_GPRs(frame)
850 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +0000851 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +0000852 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +0000853 """
854 return get_registers(frame, "general purpose")
855
856def get_FPRs(frame):
857 """Returns the floating point registers of the frame as an SBValue.
858
Johnny Chene9e86892011-05-10 23:01:44 +0000859 The returned SBValue object is iterable. An example:
860 ...
861 from lldbutil import get_FPRs
862 regs = get_FPRs(frame)
863 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +0000864 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +0000865 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +0000866 """
867 return get_registers(frame, "floating point")
868
869def get_ESRs(frame):
870 """Returns the exception state registers of the frame as an SBValue.
871
Johnny Chene9e86892011-05-10 23:01:44 +0000872 The returned SBValue object is iterable. An example:
873 ...
874 from lldbutil import get_ESRs
875 regs = get_ESRs(frame)
876 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +0000877 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +0000878 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +0000879 """
880 return get_registers(frame, "exception state")
Johnny Chen989b7ef2011-07-22 00:47:58 +0000881
Johnny Chenefee1cd2011-07-22 00:51:54 +0000882# ======================================
883# Utility classes/functions for SBValues
884# ======================================
Johnny Chen989b7ef2011-07-22 00:47:58 +0000885
886class BasicFormatter(object):
Johnny Chen36d7d912011-07-22 22:01:35 +0000887 """The basic formatter inspects the value object and prints the value."""
Johnny Chen989b7ef2011-07-22 00:47:58 +0000888 def format(self, value, buffer=None, indent=0):
889 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +0000890 output = SixStringIO()
Johnny Chen989b7ef2011-07-22 00:47:58 +0000891 else:
892 output = buffer
Johnny Chen36d7d912011-07-22 22:01:35 +0000893 # If there is a summary, it suffices.
894 val = value.GetSummary()
895 # Otherwise, get the value.
896 if val == None:
897 val = value.GetValue()
898 if val == None and value.GetNumChildren() > 0:
899 val = "%s (location)" % value.GetLocation()
Zachary Turnerff890da2015-10-19 23:45:41 +0000900 print("{indentation}({type}) {name} = {value}".format(
Johnny Chen989b7ef2011-07-22 00:47:58 +0000901 indentation = ' ' * indent,
902 type = value.GetTypeName(),
903 name = value.GetName(),
Zachary Turnerff890da2015-10-19 23:45:41 +0000904 value = val), file=output)
Johnny Chen989b7ef2011-07-22 00:47:58 +0000905 return output.getvalue()
906
907class ChildVisitingFormatter(BasicFormatter):
Johnny Chen36d7d912011-07-22 22:01:35 +0000908 """The child visiting formatter prints the value and its immediate children.
909
910 The constructor takes a keyword arg: indent_child, which defaults to 2.
911 """
912 def __init__(self, indent_child=2):
913 """Default indentation of 2 SPC's for the children."""
914 self.cindent = indent_child
Johnny Chen989b7ef2011-07-22 00:47:58 +0000915 def format(self, value, buffer=None):
916 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +0000917 output = SixStringIO()
Johnny Chen989b7ef2011-07-22 00:47:58 +0000918 else:
919 output = buffer
920
921 BasicFormatter.format(self, value, buffer=output)
922 for child in value:
Johnny Chen36d7d912011-07-22 22:01:35 +0000923 BasicFormatter.format(self, child, buffer=output, indent=self.cindent)
924
925 return output.getvalue()
926
927class RecursiveDecentFormatter(BasicFormatter):
928 """The recursive decent formatter prints the value and the decendents.
929
930 The constructor takes two keyword args: indent_level, which defaults to 0,
931 and indent_child, which defaults to 2. The current indentation level is
932 determined by indent_level, while the immediate children has an additional
933 indentation by inden_child.
934 """
935 def __init__(self, indent_level=0, indent_child=2):
936 self.lindent = indent_level
937 self.cindent = indent_child
938 def format(self, value, buffer=None):
939 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +0000940 output = SixStringIO()
Johnny Chen36d7d912011-07-22 22:01:35 +0000941 else:
942 output = buffer
943
944 BasicFormatter.format(self, value, buffer=output, indent=self.lindent)
945 new_indent = self.lindent + self.cindent
946 for child in value:
947 if child.GetSummary() != None:
948 BasicFormatter.format(self, child, buffer=output, indent=new_indent)
949 else:
950 if child.GetNumChildren() > 0:
951 rdf = RecursiveDecentFormatter(indent_level=new_indent)
952 rdf.format(child, buffer=output)
953 else:
954 BasicFormatter.format(self, child, buffer=output, indent=new_indent)
Johnny Chen989b7ef2011-07-22 00:47:58 +0000955
956 return output.getvalue()
Chaoren Lin3e2bdb42015-05-11 17:53:39 +0000957
958# ===========================================================
959# Utility functions for path manipulation on remote platforms
960# ===========================================================
961
962def join_remote_paths(*paths):
963 # TODO: update with actual platform name for remote windows once it exists
964 if lldb.remote_platform.GetName() == 'remote-windows':
965 return os.path.join(*paths).replace(os.path.sep, '\\')
966 return os.path.join(*paths).replace(os.path.sep, '/')
967
Chaoren Lin5d76b1b2015-06-06 00:25:50 +0000968def append_to_process_working_directory(*paths):
969 remote = lldb.remote_platform
970 if remote:
971 return join_remote_paths(remote.GetWorkingDirectory(), *paths)
972 return os.path.join(os.getcwd(), *paths)
Chaoren Linf59d05092015-06-02 16:46:28 +0000973
974# ==================================================
975# Utility functions to get the correct signal number
976# ==================================================
977
978import signal
979
980def get_signal_number(signal_name):
981 platform = lldb.remote_platform
Chaoren Lin98d0a4b2015-07-14 01:09:28 +0000982 if platform and platform.IsValid():
983 signals = platform.GetUnixSignals()
984 if signals.IsValid():
Chaoren Lin264e5422015-06-02 18:31:57 +0000985 signal_number = signals.GetSignalNumberFromName(signal_name)
986 if signal_number > 0:
987 return signal_number
Chaoren Lin98d0a4b2015-07-14 01:09:28 +0000988 # No remote platform; fall back to using local python signals.
Chaoren Linf59d05092015-06-02 16:46:28 +0000989 return getattr(signal, signal_name)
Enrico Granata0b5a6e32015-09-18 20:12:52 +0000990
991class PrintableRegex(object):
992 def __init__(self, text):
993 self.regex = re.compile(text)
994 self.text = text
995
996 def match(self, str):
997 return self.regex.match(str)
998
999 def __str__(self):
1000 return "%s" % (self.text)
1001
1002 def __repr__(self):
1003 return "re.compile(%s) -> %s" % (self.text, self.regex)
1004
Enrico Granataef4fa442015-12-04 19:50:05 +00001005def skip_if_callable(test, mycallable, reason):
1006 if six.callable(mycallable):
1007 if mycallable(test):
1008 test.skipTest(reason)
1009 return True
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001010 return False
1011
1012def skip_if_library_missing(test, target, library):
1013 def find_library(target, library):
1014 for module in target.modules:
1015 filename = module.file.GetFilename()
1016 if isinstance(library, str):
1017 if library == filename:
1018 return False
1019 elif hasattr(library, 'match'):
1020 if library.match(filename):
1021 return False
1022 return True
1023 def find_library_callable(test):
1024 return find_library(target, library)
1025 return skip_if_callable(test, find_library_callable, "could not find library matching '%s' in target %s" % (library, target))