blob: ea34ed6271e096ceef5f198c900916533a86848a [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 Turner44073962016-01-25 23:21:18 +000087 return bytearray(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
Zachary Turner44073962016-01-25 23:21:18 +0000111 unpacked = struct.unpack_from(fmt, 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
Zachary Turner1da094a2016-01-22 23:54:41 +0000551def get_threads_stopped_at_breakpoint_id(process, bpid):
Johnny Chend0fef812011-04-25 23:38:13 +0000552 """ 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)
Zachary Turner1da094a2016-01-22 23:54:41 +0000564 if break_id == bpid:
Johnny Chend0fef812011-04-25 23:38:13 +0000565 threads.append(thread)
566
567 return threads
568
Zachary Turner1da094a2016-01-22 23:54:41 +0000569def get_threads_stopped_at_breakpoint (process, bkpt):
570 return get_threads_stopped_at_breakpoint_id(process, bkpt.GetID())
571
572def get_one_thread_stopped_at_breakpoint_id(process, bpid, require_exactly_one = True):
573 threads = get_threads_stopped_at_breakpoint_id(process, bpid)
Zachary Turner783550b2016-01-21 21:07:30 +0000574 if len(threads) == 0:
575 return None
576 if require_exactly_one and len(threads) != 1:
577 return None
578
579 return threads[0]
580
Zachary Turner1da094a2016-01-22 23:54:41 +0000581def get_one_thread_stopped_at_breakpoint(process, bkpt, require_exactly_one = True):
Zachary Turnerec560182016-01-23 00:49:11 +0000582 return get_one_thread_stopped_at_breakpoint_id(process, bkpt.GetID(), require_exactly_one)
Zachary Turner1da094a2016-01-22 23:54:41 +0000583
Pavel Labathc4e25c92015-05-29 10:13:03 +0000584def is_thread_crashed (test, thread):
585 """In the test suite we dereference a null pointer to simulate a crash. The way this is
586 reported depends on the platform."""
587 if test.platformIsDarwin():
588 return thread.GetStopReason() == lldb.eStopReasonException and "EXC_BAD_ACCESS" in thread.GetStopDescription(100)
589 elif test.getPlatform() == "linux":
590 return thread.GetStopReason() == lldb.eStopReasonSignal and thread.GetStopReasonDataAtIndex(0) == thread.GetProcess().GetUnixSignals().GetSignalNumberFromName("SIGSEGV")
591 else:
592 return "invalid address" in thread.GetStopDescription(100)
593
594def get_crashed_threads (test, process):
595 threads = []
596 if process.GetState() != lldb.eStateStopped:
597 return threads
598 for thread in process:
599 if is_thread_crashed(test, thread):
600 threads.append(thread)
601 return threads
602
Johnny Chend0fef812011-04-25 23:38:13 +0000603def continue_to_breakpoint (process, bkpt):
604 """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None"""
605 process.Continue()
606 if process.GetState() != lldb.eStateStopped:
607 return None
608 else:
609 return get_threads_stopped_at_breakpoint (process, bkpt)
610
Johnny Chena4603162011-03-09 23:45:56 +0000611def get_caller_symbol(thread):
612 """
613 Returns the symbol name for the call site of the leaf function.
614 """
615 depth = thread.GetNumFrames()
616 if depth <= 1:
617 return None
618 caller = thread.GetFrameAtIndex(1).GetSymbol()
619 if caller:
620 return caller.GetName()
621 else:
622 return None
623
624
Johnny Chend0fef812011-04-25 23:38:13 +0000625def get_function_names(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000626 """
627 Returns a sequence of function names from the stack frames of this thread.
628 """
629 def GetFuncName(i):
Johnny Chen4cfd07e2011-06-20 00:26:39 +0000630 return thread.GetFrameAtIndex(i).GetFunctionName()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000631
Zachary Turner744cd5d2015-10-26 16:49:57 +0000632 return list(map(GetFuncName, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000633
634
Johnny Chend0fef812011-04-25 23:38:13 +0000635def get_symbol_names(thread):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000636 """
637 Returns a sequence of symbols for this thread.
638 """
639 def GetSymbol(i):
640 return thread.GetFrameAtIndex(i).GetSymbol().GetName()
641
Zachary Turner744cd5d2015-10-26 16:49:57 +0000642 return list(map(GetSymbol, list(range(thread.GetNumFrames()))))
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000643
644
Johnny Chend0fef812011-04-25 23:38:13 +0000645def get_pc_addresses(thread):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000646 """
647 Returns a sequence of pc addresses for this thread.
648 """
649 def GetPCAddress(i):
650 return thread.GetFrameAtIndex(i).GetPCAddress()
651
Zachary Turner744cd5d2015-10-26 16:49:57 +0000652 return list(map(GetPCAddress, list(range(thread.GetNumFrames()))))
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000653
654
Johnny Chend0fef812011-04-25 23:38:13 +0000655def get_filenames(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000656 """
657 Returns a sequence of file names from the stack frames of this thread.
658 """
659 def GetFilename(i):
660 return thread.GetFrameAtIndex(i).GetLineEntry().GetFileSpec().GetFilename()
661
Zachary Turner744cd5d2015-10-26 16:49:57 +0000662 return list(map(GetFilename, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000663
664
Johnny Chend0fef812011-04-25 23:38:13 +0000665def get_line_numbers(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000666 """
667 Returns a sequence of line numbers from the stack frames of this thread.
668 """
669 def GetLineNumber(i):
670 return thread.GetFrameAtIndex(i).GetLineEntry().GetLine()
671
Zachary Turner744cd5d2015-10-26 16:49:57 +0000672 return list(map(GetLineNumber, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000673
674
Johnny Chend0fef812011-04-25 23:38:13 +0000675def get_module_names(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000676 """
677 Returns a sequence of module names from the stack frames of this thread.
678 """
679 def GetModuleName(i):
680 return thread.GetFrameAtIndex(i).GetModule().GetFileSpec().GetFilename()
681
Zachary Turner744cd5d2015-10-26 16:49:57 +0000682 return list(map(GetModuleName, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000683
684
Johnny Chend0fef812011-04-25 23:38:13 +0000685def get_stack_frames(thread):
Johnny Chen43a651c2010-09-09 00:55:07 +0000686 """
687 Returns a sequence of stack frames for this thread.
688 """
689 def GetStackFrame(i):
690 return thread.GetFrameAtIndex(i)
691
Zachary Turner744cd5d2015-10-26 16:49:57 +0000692 return list(map(GetStackFrame, list(range(thread.GetNumFrames()))))
Johnny Chen43a651c2010-09-09 00:55:07 +0000693
694
Johnny Chend0fef812011-04-25 23:38:13 +0000695def print_stacktrace(thread, string_buffer = False):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000696 """Prints a simple stack trace of this thread."""
Johnny Chen6c704992010-10-07 18:52:48 +0000697
Zachary Turner814236d2015-10-21 17:48:52 +0000698 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000699 target = thread.GetProcess().GetTarget()
700
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000701 depth = thread.GetNumFrames()
702
Johnny Chend0fef812011-04-25 23:38:13 +0000703 mods = get_module_names(thread)
704 funcs = get_function_names(thread)
705 symbols = get_symbol_names(thread)
706 files = get_filenames(thread)
707 lines = get_line_numbers(thread)
708 addrs = get_pc_addresses(thread)
Johnny Chen6c704992010-10-07 18:52:48 +0000709
Johnny Chen567a0452010-10-25 19:13:52 +0000710 if thread.GetStopReason() != lldb.eStopReasonInvalid:
Johnny Chende90f1d2011-04-27 17:43:07 +0000711 desc = "stop reason=" + stop_reason_to_str(thread.GetStopReason())
Johnny Chen567a0452010-10-25 19:13:52 +0000712 else:
713 desc = ""
Zachary Turnerff890da2015-10-19 23:45:41 +0000714 print("Stack trace for thread id={0:#x} name={1} queue={2} ".format(
715 thread.GetThreadID(), thread.GetName(), thread.GetQueueName()) + desc, file=output)
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000716
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000717 for i in range(depth):
718 frame = thread.GetFrameAtIndex(i)
719 function = frame.GetFunction()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000720
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000721 load_addr = addrs[i].GetLoadAddress(target)
Johnny Chen3cd1e552011-05-25 19:06:18 +0000722 if not function:
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000723 file_addr = addrs[i].GetFileAddress()
Johnny Chen0d4f6dd2011-06-16 22:07:48 +0000724 start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress()
725 symbol_offset = file_addr - start_addr
Zachary Turnerff890da2015-10-19 23:45:41 +0000726 print(" frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format(
727 num=i, addr=load_addr, mod=mods[i], symbol=symbols[i], offset=symbol_offset), file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000728 else:
Zachary Turnerff890da2015-10-19 23:45:41 +0000729 print(" frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format(
Johnny Chen4cfd07e2011-06-20 00:26:39 +0000730 num=i, addr=load_addr, mod=mods[i],
731 func='%s [inlined]' % funcs[i] if frame.IsInlined() else funcs[i],
Johnny Chen13ea11a2011-07-13 22:34:29 +0000732 file=files[i], line=lines[i],
Zachary Turnerff890da2015-10-19 23:45:41 +0000733 args=get_args_as_string(frame, showFuncName=False) if not frame.IsInlined() else '()'), file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000734
735 if string_buffer:
Johnny Chend5d6fac2010-10-15 23:33:18 +0000736 return output.getvalue()
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000737
738
Johnny Chend0fef812011-04-25 23:38:13 +0000739def print_stacktraces(process, string_buffer = False):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000740 """Prints the stack traces of all the threads."""
741
Zachary Turner814236d2015-10-21 17:48:52 +0000742 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000743
Zachary Turnerff890da2015-10-19 23:45:41 +0000744 print("Stack traces for " + str(process), file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000745
Johnny Chenae9639a2011-05-05 18:50:56 +0000746 for thread in process:
Zachary Turnerff890da2015-10-19 23:45:41 +0000747 print(print_stacktrace(thread, string_buffer=True), file=output)
Johnny Chen6c704992010-10-07 18:52:48 +0000748
749 if string_buffer:
Johnny Chend5d6fac2010-10-15 23:33:18 +0000750 return output.getvalue()
Johnny Chenb21c52e2011-05-08 17:25:27 +0000751
Pavel Labath5dcb0252015-09-02 09:12:28 +0000752def expect_state_changes(test, listener, states, timeout = 5):
753 """Listens for state changed events on the listener and makes sure they match what we
754 expect. Stop-and-restart events (where GetRestartedFromEvent() returns true) are ignored."""
Pavel Labathe5c98082016-01-06 11:40:06 +0000755
Pavel Labath5dcb0252015-09-02 09:12:28 +0000756 for expected_state in states:
Pavel Labathe5c98082016-01-06 11:40:06 +0000757 def get_next_event():
758 event = lldb.SBEvent()
759 if not listener.WaitForEvent(timeout, event):
760 test.fail("Timed out while waiting for a transition to state %s" %
761 lldb.SBDebugger.StateAsCString(expected_state))
762 return event
Pavel Labath5dcb0252015-09-02 09:12:28 +0000763
Pavel Labathe5c98082016-01-06 11:40:06 +0000764 event = get_next_event()
765 while (lldb.SBProcess.GetStateFromEvent(event) == lldb.eStateStopped and
766 lldb.SBProcess.GetRestartedFromEvent(event)):
767 # Ignore restarted event and the subsequent running event.
768 event = get_next_event()
769 test.assertEqual(lldb.SBProcess.GetStateFromEvent(event), lldb.eStateRunning,
770 "Restarted event followed by a running event")
771 event = get_next_event()
Pavel Labath5dcb0252015-09-02 09:12:28 +0000772
Pavel Labathe5c98082016-01-06 11:40:06 +0000773 test.assertEqual(lldb.SBProcess.GetStateFromEvent(event), expected_state)
Pavel Labath5dcb0252015-09-02 09:12:28 +0000774
Johnny Chenb21c52e2011-05-08 17:25:27 +0000775# ===================================
776# Utility functions related to Frames
777# ===================================
778
Johnny Chenad7372c2011-05-12 00:32:41 +0000779def get_parent_frame(frame):
780 """
781 Returns the parent frame of the input frame object; None if not available.
782 """
783 thread = frame.GetThread()
784 parent_found = False
785 for f in thread:
786 if parent_found:
787 return f
788 if f.GetFrameID() == frame.GetFrameID():
789 parent_found = True
790
791 # If we reach here, no parent has been found, return None.
792 return None
793
Johnny Chen0d4f6dd2011-06-16 22:07:48 +0000794def get_args_as_string(frame, showFuncName=True):
Johnny Chenad7372c2011-05-12 00:32:41 +0000795 """
796 Returns the args of the input frame object as a string.
797 """
798 # arguments => True
799 # locals => False
800 # statics => False
801 # in_scope_only => True
802 vars = frame.GetVariables(True, False, False, True) # type of SBValueList
803 args = [] # list of strings
804 for var in vars:
805 args.append("(%s)%s=%s" % (var.GetTypeName(),
806 var.GetName(),
Greg Claytonfe42ac42011-08-03 22:57:10 +0000807 var.GetValue()))
Johnny Chen3cd1e552011-05-25 19:06:18 +0000808 if frame.GetFunction():
Johnny Chen52b0ffd92011-05-13 00:44:49 +0000809 name = frame.GetFunction().GetName()
Johnny Chen3cd1e552011-05-25 19:06:18 +0000810 elif frame.GetSymbol():
Johnny Chen52b0ffd92011-05-13 00:44:49 +0000811 name = frame.GetSymbol().GetName()
812 else:
813 name = ""
Johnny Chen0d4f6dd2011-06-16 22:07:48 +0000814 if showFuncName:
815 return "%s(%s)" % (name, ", ".join(args))
816 else:
817 return "(%s)" % (", ".join(args))
818
Johnny Chenb21c52e2011-05-08 17:25:27 +0000819def print_registers(frame, string_buffer = False):
Johnny Chen2158b972011-05-08 18:55:37 +0000820 """Prints all the register sets of the frame."""
Johnny Chenb21c52e2011-05-08 17:25:27 +0000821
Zachary Turner814236d2015-10-21 17:48:52 +0000822 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chenb21c52e2011-05-08 17:25:27 +0000823
Zachary Turnerff890da2015-10-19 23:45:41 +0000824 print("Register sets for " + str(frame), file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +0000825
Johnny Chen64ff7e62011-05-10 19:21:13 +0000826 registerSet = frame.GetRegisters() # Return type of SBValueList.
Zachary Turnerff890da2015-10-19 23:45:41 +0000827 print("Frame registers (size of register set = %d):" % registerSet.GetSize(), file=output)
Johnny Chen64ff7e62011-05-10 19:21:13 +0000828 for value in registerSet:
Zachary Turner35d017f2015-10-23 17:04:29 +0000829 #print(value, file=output)
Zachary Turnerff890da2015-10-19 23:45:41 +0000830 print("%s (number of children = %d):" % (value.GetName(), value.GetNumChildren()), file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +0000831 for child in value:
Zachary Turnerff890da2015-10-19 23:45:41 +0000832 print("Name: %s, Value: %s" % (child.GetName(), child.GetValue()), file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +0000833
834 if string_buffer:
835 return output.getvalue()
Johnny Chen64ff7e62011-05-10 19:21:13 +0000836
837def get_registers(frame, kind):
838 """Returns the registers given the frame and the kind of registers desired.
839
840 Returns None if there's no such kind.
841 """
842 registerSet = frame.GetRegisters() # Return type of SBValueList.
843 for value in registerSet:
844 if kind.lower() in value.GetName().lower():
845 return value
846
847 return None
848
849def get_GPRs(frame):
850 """Returns the general purpose registers of the frame as an SBValue.
851
Johnny Chene9e86892011-05-10 23:01:44 +0000852 The returned SBValue object is iterable. An example:
853 ...
854 from lldbutil import get_GPRs
855 regs = get_GPRs(frame)
856 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +0000857 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +0000858 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +0000859 """
860 return get_registers(frame, "general purpose")
861
862def get_FPRs(frame):
863 """Returns the floating point registers of the frame as an SBValue.
864
Johnny Chene9e86892011-05-10 23:01:44 +0000865 The returned SBValue object is iterable. An example:
866 ...
867 from lldbutil import get_FPRs
868 regs = get_FPRs(frame)
869 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +0000870 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +0000871 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +0000872 """
873 return get_registers(frame, "floating point")
874
875def get_ESRs(frame):
876 """Returns the exception state registers of the frame as an SBValue.
877
Johnny Chene9e86892011-05-10 23:01:44 +0000878 The returned SBValue object is iterable. An example:
879 ...
880 from lldbutil import get_ESRs
881 regs = get_ESRs(frame)
882 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +0000883 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +0000884 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +0000885 """
886 return get_registers(frame, "exception state")
Johnny Chen989b7ef2011-07-22 00:47:58 +0000887
Johnny Chenefee1cd2011-07-22 00:51:54 +0000888# ======================================
889# Utility classes/functions for SBValues
890# ======================================
Johnny Chen989b7ef2011-07-22 00:47:58 +0000891
892class BasicFormatter(object):
Johnny Chen36d7d912011-07-22 22:01:35 +0000893 """The basic formatter inspects the value object and prints the value."""
Johnny Chen989b7ef2011-07-22 00:47:58 +0000894 def format(self, value, buffer=None, indent=0):
895 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +0000896 output = SixStringIO()
Johnny Chen989b7ef2011-07-22 00:47:58 +0000897 else:
898 output = buffer
Johnny Chen36d7d912011-07-22 22:01:35 +0000899 # If there is a summary, it suffices.
900 val = value.GetSummary()
901 # Otherwise, get the value.
902 if val == None:
903 val = value.GetValue()
904 if val == None and value.GetNumChildren() > 0:
905 val = "%s (location)" % value.GetLocation()
Zachary Turnerff890da2015-10-19 23:45:41 +0000906 print("{indentation}({type}) {name} = {value}".format(
Johnny Chen989b7ef2011-07-22 00:47:58 +0000907 indentation = ' ' * indent,
908 type = value.GetTypeName(),
909 name = value.GetName(),
Zachary Turnerff890da2015-10-19 23:45:41 +0000910 value = val), file=output)
Johnny Chen989b7ef2011-07-22 00:47:58 +0000911 return output.getvalue()
912
913class ChildVisitingFormatter(BasicFormatter):
Johnny Chen36d7d912011-07-22 22:01:35 +0000914 """The child visiting formatter prints the value and its immediate children.
915
916 The constructor takes a keyword arg: indent_child, which defaults to 2.
917 """
918 def __init__(self, indent_child=2):
919 """Default indentation of 2 SPC's for the children."""
920 self.cindent = indent_child
Johnny Chen989b7ef2011-07-22 00:47:58 +0000921 def format(self, value, buffer=None):
922 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +0000923 output = SixStringIO()
Johnny Chen989b7ef2011-07-22 00:47:58 +0000924 else:
925 output = buffer
926
927 BasicFormatter.format(self, value, buffer=output)
928 for child in value:
Johnny Chen36d7d912011-07-22 22:01:35 +0000929 BasicFormatter.format(self, child, buffer=output, indent=self.cindent)
930
931 return output.getvalue()
932
933class RecursiveDecentFormatter(BasicFormatter):
934 """The recursive decent formatter prints the value and the decendents.
935
936 The constructor takes two keyword args: indent_level, which defaults to 0,
937 and indent_child, which defaults to 2. The current indentation level is
938 determined by indent_level, while the immediate children has an additional
939 indentation by inden_child.
940 """
941 def __init__(self, indent_level=0, indent_child=2):
942 self.lindent = indent_level
943 self.cindent = indent_child
944 def format(self, value, buffer=None):
945 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +0000946 output = SixStringIO()
Johnny Chen36d7d912011-07-22 22:01:35 +0000947 else:
948 output = buffer
949
950 BasicFormatter.format(self, value, buffer=output, indent=self.lindent)
951 new_indent = self.lindent + self.cindent
952 for child in value:
953 if child.GetSummary() != None:
954 BasicFormatter.format(self, child, buffer=output, indent=new_indent)
955 else:
956 if child.GetNumChildren() > 0:
957 rdf = RecursiveDecentFormatter(indent_level=new_indent)
958 rdf.format(child, buffer=output)
959 else:
960 BasicFormatter.format(self, child, buffer=output, indent=new_indent)
Johnny Chen989b7ef2011-07-22 00:47:58 +0000961
962 return output.getvalue()
Chaoren Lin3e2bdb42015-05-11 17:53:39 +0000963
964# ===========================================================
965# Utility functions for path manipulation on remote platforms
966# ===========================================================
967
968def join_remote_paths(*paths):
969 # TODO: update with actual platform name for remote windows once it exists
970 if lldb.remote_platform.GetName() == 'remote-windows':
971 return os.path.join(*paths).replace(os.path.sep, '\\')
972 return os.path.join(*paths).replace(os.path.sep, '/')
973
Chaoren Lin5d76b1b2015-06-06 00:25:50 +0000974def append_to_process_working_directory(*paths):
975 remote = lldb.remote_platform
976 if remote:
977 return join_remote_paths(remote.GetWorkingDirectory(), *paths)
978 return os.path.join(os.getcwd(), *paths)
Chaoren Linf59d05092015-06-02 16:46:28 +0000979
980# ==================================================
981# Utility functions to get the correct signal number
982# ==================================================
983
984import signal
985
986def get_signal_number(signal_name):
987 platform = lldb.remote_platform
Chaoren Lin98d0a4b2015-07-14 01:09:28 +0000988 if platform and platform.IsValid():
989 signals = platform.GetUnixSignals()
990 if signals.IsValid():
Chaoren Lin264e5422015-06-02 18:31:57 +0000991 signal_number = signals.GetSignalNumberFromName(signal_name)
992 if signal_number > 0:
993 return signal_number
Chaoren Lin98d0a4b2015-07-14 01:09:28 +0000994 # No remote platform; fall back to using local python signals.
Chaoren Linf59d05092015-06-02 16:46:28 +0000995 return getattr(signal, signal_name)
Enrico Granata0b5a6e32015-09-18 20:12:52 +0000996
997class PrintableRegex(object):
998 def __init__(self, text):
999 self.regex = re.compile(text)
1000 self.text = text
1001
1002 def match(self, str):
1003 return self.regex.match(str)
1004
1005 def __str__(self):
1006 return "%s" % (self.text)
1007
1008 def __repr__(self):
1009 return "re.compile(%s) -> %s" % (self.text, self.regex)
1010
Enrico Granataef4fa442015-12-04 19:50:05 +00001011def skip_if_callable(test, mycallable, reason):
1012 if six.callable(mycallable):
1013 if mycallable(test):
1014 test.skipTest(reason)
1015 return True
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001016 return False
1017
1018def skip_if_library_missing(test, target, library):
1019 def find_library(target, library):
1020 for module in target.modules:
1021 filename = module.file.GetFilename()
1022 if isinstance(library, str):
1023 if library == filename:
1024 return False
1025 elif hasattr(library, 'match'):
1026 if library.match(filename):
1027 return False
1028 return True
1029 def find_library_callable(test):
1030 return find_library(target, library)
1031 return skip_if_callable(test, find_library_callable, "could not find library matching '%s' in target %s" % (library, target))