blob: 5cb1cc48a02daadbf9aa1d094cce7b0b726ed2ad [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
Adrian Prantl5ec76fe2018-01-30 18:29:16 +000012import errno
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000013import os
Enrico Granata0b5a6e32015-09-18 20:12:52 +000014import re
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000015import sys
Pavel Labatha95e0ef2016-04-06 08:55:31 +000016import time
Johnny Chen30ee4ef2010-09-08 22:54:46 +000017
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000018# Third-party modules
Zachary Turner814236d2015-10-21 17:48:52 +000019from six import StringIO as SixStringIO
Zachary Turnercd236b82015-10-26 18:48:24 +000020import six
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000021
22# LLDB modules
23import lldb
24
Zachary Turner814236d2015-10-21 17:48:52 +000025
Johnny Chen6424b7d2011-04-26 23:07:40 +000026# ===================================================
27# Utilities for locating/checking executable programs
28# ===================================================
Johnny Chen4fdcebd2011-04-26 22:53:38 +000029
Johnny Chenac77f3b2011-03-23 20:28:59 +000030def is_exe(fpath):
Johnny Chen35ec6742011-04-26 23:10:15 +000031 """Returns True if fpath is an executable."""
Johnny Chenac77f3b2011-03-23 20:28:59 +000032 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
33
Kate Stoneb9c1b512016-09-06 20:57:50 +000034
Johnny Chenac77f3b2011-03-23 20:28:59 +000035def which(program):
Johnny Chen35ec6742011-04-26 23:10:15 +000036 """Returns the full path to a program; None otherwise."""
Johnny Chenac77f3b2011-03-23 20:28:59 +000037 fpath, fname = os.path.split(program)
38 if fpath:
39 if is_exe(program):
40 return program
41 else:
42 for path in os.environ["PATH"].split(os.pathsep):
43 exe_file = os.path.join(path, program)
44 if is_exe(exe_file):
45 return exe_file
46 return None
47
Adrian Prantl5ec76fe2018-01-30 18:29:16 +000048def mkdir_p(path):
49 try:
50 os.makedirs(path)
51 except OSError as e:
52 if e.errno != errno.EEXIST:
53 raise
54 if not os.path.isdir(path):
55 raise OSError(errno.ENOTDIR, "%s is not a directory"%path)
Johnny Chened401982011-03-03 19:14:00 +000056# ===================================================
57# Disassembly for an SBFunction or an SBSymbol object
58# ===================================================
59
Kate Stoneb9c1b512016-09-06 20:57:50 +000060
Johnny Chened401982011-03-03 19:14:00 +000061def disassemble(target, function_or_symbol):
62 """Disassemble the function or symbol given a target.
63
64 It returns the disassembly content in a string object.
65 """
Zachary Turner814236d2015-10-21 17:48:52 +000066 buf = SixStringIO()
Johnny Chened401982011-03-03 19:14:00 +000067 insts = function_or_symbol.GetInstructions(target)
Johnny Chene69c7482011-04-28 22:57:01 +000068 for i in insts:
Zachary Turnerff890da2015-10-19 23:45:41 +000069 print(i, file=buf)
Johnny Chened401982011-03-03 19:14:00 +000070 return buf.getvalue()
71
Johnny Chen43766d62011-03-02 01:36:45 +000072# ==========================================================
73# Integer (byte size 1, 2, 4, and 8) to bytearray conversion
74# ==========================================================
75
Kate Stoneb9c1b512016-09-06 20:57:50 +000076
Johnny Chen43766d62011-03-02 01:36:45 +000077def int_to_bytearray(val, bytesize):
78 """Utility function to convert an integer into a bytearray.
79
Johnny Chen43e587c2011-03-02 20:54:22 +000080 It returns the bytearray in the little endian format. It is easy to get the
81 big endian format, just do ba.reverse() on the returned object.
Johnny Chen43766d62011-03-02 01:36:45 +000082 """
Johnny Chen90bb9052011-03-30 17:54:35 +000083 import struct
Johnny Chen43766d62011-03-02 01:36:45 +000084
85 if bytesize == 1:
86 return bytearray([val])
87
88 # Little endian followed by a format character.
89 template = "<%c"
90 if bytesize == 2:
91 fmt = template % 'h'
92 elif bytesize == 4:
93 fmt = template % 'i'
94 elif bytesize == 4:
95 fmt = template % 'q'
96 else:
97 return None
98
Johnny Chen90bb9052011-03-30 17:54:35 +000099 packed = struct.pack(fmt, val)
Zachary Turner44073962016-01-25 23:21:18 +0000100 return bytearray(packed)
Johnny Chen43766d62011-03-02 01:36:45 +0000101
Kate Stoneb9c1b512016-09-06 20:57:50 +0000102
Johnny Chen43766d62011-03-02 01:36:45 +0000103def bytearray_to_int(bytes, bytesize):
104 """Utility function to convert a bytearray into an integer.
105
Johnny Chen43e587c2011-03-02 20:54:22 +0000106 It interprets the bytearray in the little endian format. For a big endian
107 bytearray, just do ba.reverse() on the object before passing it in.
Johnny Chen43766d62011-03-02 01:36:45 +0000108 """
Johnny Chen90bb9052011-03-30 17:54:35 +0000109 import struct
Johnny Chen43766d62011-03-02 01:36:45 +0000110
111 if bytesize == 1:
Filipe Cabecinhas5d261b02012-07-06 16:20:13 +0000112 return bytes[0]
Johnny Chen43766d62011-03-02 01:36:45 +0000113
114 # Little endian followed by a format character.
115 template = "<%c"
116 if bytesize == 2:
117 fmt = template % 'h'
118 elif bytesize == 4:
119 fmt = template % 'i'
120 elif bytesize == 4:
121 fmt = template % 'q'
122 else:
123 return None
124
Zachary Turner44073962016-01-25 23:21:18 +0000125 unpacked = struct.unpack_from(fmt, bytes)
Johnny Chen43766d62011-03-02 01:36:45 +0000126 return unpacked[0]
127
128
Johnny Chen90256cd2011-04-23 00:13:34 +0000129# ==============================================================
130# Get the description of an lldb object or None if not available
131# ==============================================================
Johnny Chenfc87e2d2011-04-25 20:23:05 +0000132def get_description(obj, option=None):
133 """Calls lldb_obj.GetDescription() and returns a string, or None.
134
Johnny Chen01a67862011-10-14 00:42:25 +0000135 For SBTarget, SBBreakpointLocation, and SBWatchpoint lldb objects, an extra
136 option can be passed in to describe the detailed level of description
137 desired:
Johnny Chenfc87e2d2011-04-25 20:23:05 +0000138 o lldb.eDescriptionLevelBrief
139 o lldb.eDescriptionLevelFull
140 o lldb.eDescriptionLevelVerbose
141 """
142 method = getattr(obj, 'GetDescription')
Johnny Chen90256cd2011-04-23 00:13:34 +0000143 if not method:
144 return None
Johnny Chen01a67862011-10-14 00:42:25 +0000145 tuple = (lldb.SBTarget, lldb.SBBreakpointLocation, lldb.SBWatchpoint)
Johnny Chen469683e2011-09-27 21:27:19 +0000146 if isinstance(obj, tuple):
Johnny Chenfc87e2d2011-04-25 20:23:05 +0000147 if option is None:
148 option = lldb.eDescriptionLevelBrief
149
Johnny Chen90256cd2011-04-23 00:13:34 +0000150 stream = lldb.SBStream()
151 if option is None:
152 success = method(stream)
153 else:
154 success = method(stream, option)
155 if not success:
156 return None
157 return stream.GetData()
Kate Stoneb9c1b512016-09-06 20:57:50 +0000158
Johnny Chen90256cd2011-04-23 00:13:34 +0000159
Johnny Chenf4f70bb2010-10-22 21:31:03 +0000160# =================================================
161# Convert some enum value to its string counterpart
162# =================================================
Johnny Chen28ae2942010-10-07 22:15:58 +0000163
Johnny Chende90f1d2011-04-27 17:43:07 +0000164def state_type_to_str(enum):
Johnny Chen28ae2942010-10-07 22:15:58 +0000165 """Returns the stateType string given an enum."""
166 if enum == lldb.eStateInvalid:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000167 return "invalid"
Johnny Chen28ae2942010-10-07 22:15:58 +0000168 elif enum == lldb.eStateUnloaded:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000169 return "unloaded"
Johnny Chen930e3ad2011-03-05 01:20:11 +0000170 elif enum == lldb.eStateConnected:
171 return "connected"
Johnny Chen28ae2942010-10-07 22:15:58 +0000172 elif enum == lldb.eStateAttaching:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000173 return "attaching"
Johnny Chen28ae2942010-10-07 22:15:58 +0000174 elif enum == lldb.eStateLaunching:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000175 return "launching"
Johnny Chen28ae2942010-10-07 22:15:58 +0000176 elif enum == lldb.eStateStopped:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000177 return "stopped"
Johnny Chen28ae2942010-10-07 22:15:58 +0000178 elif enum == lldb.eStateRunning:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000179 return "running"
Johnny Chen28ae2942010-10-07 22:15:58 +0000180 elif enum == lldb.eStateStepping:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000181 return "stepping"
Johnny Chen28ae2942010-10-07 22:15:58 +0000182 elif enum == lldb.eStateCrashed:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000183 return "crashed"
Johnny Chen28ae2942010-10-07 22:15:58 +0000184 elif enum == lldb.eStateDetached:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000185 return "detached"
Johnny Chen28ae2942010-10-07 22:15:58 +0000186 elif enum == lldb.eStateExited:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000187 return "exited"
Johnny Chen28ae2942010-10-07 22:15:58 +0000188 elif enum == lldb.eStateSuspended:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000189 return "suspended"
Johnny Chen28ae2942010-10-07 22:15:58 +0000190 else:
Johnny Chen930e3ad2011-03-05 01:20:11 +0000191 raise Exception("Unknown StateType enum")
Johnny Chen28ae2942010-10-07 22:15:58 +0000192
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193
Johnny Chende90f1d2011-04-27 17:43:07 +0000194def stop_reason_to_str(enum):
Johnny Chen28ae2942010-10-07 22:15:58 +0000195 """Returns the stopReason string given an enum."""
196 if enum == lldb.eStopReasonInvalid:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000197 return "invalid"
Johnny Chen28ae2942010-10-07 22:15:58 +0000198 elif enum == lldb.eStopReasonNone:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000199 return "none"
Johnny Chen28ae2942010-10-07 22:15:58 +0000200 elif enum == lldb.eStopReasonTrace:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000201 return "trace"
Johnny Chen28ae2942010-10-07 22:15:58 +0000202 elif enum == lldb.eStopReasonBreakpoint:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000203 return "breakpoint"
Johnny Chen28ae2942010-10-07 22:15:58 +0000204 elif enum == lldb.eStopReasonWatchpoint:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000205 return "watchpoint"
Jim Ingham6cc0d2f2014-04-03 01:25:28 +0000206 elif enum == lldb.eStopReasonExec:
207 return "exec"
Johnny Chen28ae2942010-10-07 22:15:58 +0000208 elif enum == lldb.eStopReasonSignal:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000209 return "signal"
Johnny Chen28ae2942010-10-07 22:15:58 +0000210 elif enum == lldb.eStopReasonException:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000211 return "exception"
Johnny Chen28ae2942010-10-07 22:15:58 +0000212 elif enum == lldb.eStopReasonPlanComplete:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000213 return "plancomplete"
Daniel Maleab3d41a22013-07-09 00:08:01 +0000214 elif enum == lldb.eStopReasonThreadExiting:
215 return "threadexiting"
Johnny Chen28ae2942010-10-07 22:15:58 +0000216 else:
Johnny Chen930e3ad2011-03-05 01:20:11 +0000217 raise Exception("Unknown StopReason enum")
Johnny Chen28ae2942010-10-07 22:15:58 +0000218
Kate Stoneb9c1b512016-09-06 20:57:50 +0000219
Johnny Chena32a13d2011-09-28 00:51:00 +0000220def symbol_type_to_str(enum):
221 """Returns the symbolType string given an enum."""
222 if enum == lldb.eSymbolTypeInvalid:
223 return "invalid"
224 elif enum == lldb.eSymbolTypeAbsolute:
225 return "absolute"
Johnny Chena32a13d2011-09-28 00:51:00 +0000226 elif enum == lldb.eSymbolTypeCode:
227 return "code"
228 elif enum == lldb.eSymbolTypeData:
229 return "data"
230 elif enum == lldb.eSymbolTypeTrampoline:
231 return "trampoline"
232 elif enum == lldb.eSymbolTypeRuntime:
233 return "runtime"
234 elif enum == lldb.eSymbolTypeException:
235 return "exception"
236 elif enum == lldb.eSymbolTypeSourceFile:
237 return "sourcefile"
238 elif enum == lldb.eSymbolTypeHeaderFile:
239 return "headerfile"
240 elif enum == lldb.eSymbolTypeObjectFile:
241 return "objectfile"
242 elif enum == lldb.eSymbolTypeCommonBlock:
243 return "commonblock"
244 elif enum == lldb.eSymbolTypeBlock:
245 return "block"
246 elif enum == lldb.eSymbolTypeLocal:
247 return "local"
248 elif enum == lldb.eSymbolTypeParam:
249 return "param"
250 elif enum == lldb.eSymbolTypeVariable:
251 return "variable"
252 elif enum == lldb.eSymbolTypeVariableType:
253 return "variabletype"
254 elif enum == lldb.eSymbolTypeLineEntry:
255 return "lineentry"
256 elif enum == lldb.eSymbolTypeLineHeader:
257 return "lineheader"
258 elif enum == lldb.eSymbolTypeScopeBegin:
259 return "scopebegin"
260 elif enum == lldb.eSymbolTypeScopeEnd:
261 return "scopeend"
262 elif enum == lldb.eSymbolTypeAdditional:
263 return "additional"
264 elif enum == lldb.eSymbolTypeCompiler:
265 return "compiler"
266 elif enum == lldb.eSymbolTypeInstrumentation:
267 return "instrumentation"
268 elif enum == lldb.eSymbolTypeUndefined:
269 return "undefined"
270
Kate Stoneb9c1b512016-09-06 20:57:50 +0000271
Johnny Chende90f1d2011-04-27 17:43:07 +0000272def value_type_to_str(enum):
Johnny Chen87bb5892010-11-03 21:37:58 +0000273 """Returns the valueType string given an enum."""
274 if enum == lldb.eValueTypeInvalid:
275 return "invalid"
276 elif enum == lldb.eValueTypeVariableGlobal:
277 return "global_variable"
278 elif enum == lldb.eValueTypeVariableStatic:
279 return "static_variable"
280 elif enum == lldb.eValueTypeVariableArgument:
281 return "argument_variable"
282 elif enum == lldb.eValueTypeVariableLocal:
283 return "local_variable"
284 elif enum == lldb.eValueTypeRegister:
285 return "register"
286 elif enum == lldb.eValueTypeRegisterSet:
287 return "register_set"
288 elif enum == lldb.eValueTypeConstResult:
289 return "constant_result"
290 else:
Johnny Chen930e3ad2011-03-05 01:20:11 +0000291 raise Exception("Unknown ValueType enum")
Johnny Chen87bb5892010-11-03 21:37:58 +0000292
Johnny Chen28ae2942010-10-07 22:15:58 +0000293
Johnny Chenf4f70bb2010-10-22 21:31:03 +0000294# ==================================================
Daniel Maleab3d41a22013-07-09 00:08:01 +0000295# Get stopped threads due to each stop reason.
296# ==================================================
297
298def sort_stopped_threads(process,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000299 breakpoint_threads=None,
300 crashed_threads=None,
301 watchpoint_threads=None,
302 signal_threads=None,
303 exiting_threads=None,
304 other_threads=None):
Daniel Maleab3d41a22013-07-09 00:08:01 +0000305 """ Fills array *_threads with threads stopped for the corresponding stop
306 reason.
307 """
308 for lst in [breakpoint_threads,
309 watchpoint_threads,
310 signal_threads,
311 exiting_threads,
312 other_threads]:
313 if lst is not None:
314 lst[:] = []
315
316 for thread in process:
317 dispatched = False
318 for (reason, list) in [(lldb.eStopReasonBreakpoint, breakpoint_threads),
319 (lldb.eStopReasonException, crashed_threads),
320 (lldb.eStopReasonWatchpoint, watchpoint_threads),
321 (lldb.eStopReasonSignal, signal_threads),
322 (lldb.eStopReasonThreadExiting, exiting_threads),
323 (None, other_threads)]:
324 if not dispatched and list is not None:
325 if thread.GetStopReason() == reason or reason is None:
326 list.append(thread)
327 dispatched = True
328
329# ==================================================
Jim Ingham63dfc722012-09-22 00:05:11 +0000330# Utility functions for setting breakpoints
331# ==================================================
332
Kate Stoneb9c1b512016-09-06 20:57:50 +0000333
334def run_break_set_by_file_and_line(
335 test,
336 file_name,
337 line_number,
338 extra_options=None,
339 num_expected_locations=1,
340 loc_exact=False,
341 module_name=None):
342 """Set a breakpoint by file and line, returning the breakpoint number.
Jim Ingham63dfc722012-09-22 00:05:11 +0000343
344 If extra_options is not None, then we append it to the breakpoint set command.
345
346 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.
347
348 If loc_exact is true, we check that there is one location, and that location must be at the input file and line number."""
349
Kate Stoneb9c1b512016-09-06 20:57:50 +0000350 if file_name is None:
351 command = 'breakpoint set -l %d' % (line_number)
Jim Ingham63dfc722012-09-22 00:05:11 +0000352 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000353 command = 'breakpoint set -f "%s" -l %d' % (file_name, line_number)
Jim Ingham63dfc722012-09-22 00:05:11 +0000354
Greg Claytonc1b2ccf2013-01-08 00:01:36 +0000355 if module_name:
356 command += " --shlib '%s'" % (module_name)
357
Jim Ingham63dfc722012-09-22 00:05:11 +0000358 if extra_options:
359 command += " " + extra_options
360
Kate Stoneb9c1b512016-09-06 20:57:50 +0000361 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000362
363 if num_expected_locations == 1 and loc_exact:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000364 check_breakpoint_result(
365 test,
366 break_results,
367 num_locations=num_expected_locations,
368 file_name=file_name,
369 line_number=line_number,
370 module_name=module_name)
Jim Ingham63dfc722012-09-22 00:05:11 +0000371 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000372 check_breakpoint_result(
373 test,
374 break_results,
375 num_locations=num_expected_locations)
Jim Ingham63dfc722012-09-22 00:05:11 +0000376
Kate Stoneb9c1b512016-09-06 20:57:50 +0000377 return get_bpno_from_match(break_results)
Jim Ingham63dfc722012-09-22 00:05:11 +0000378
Kate Stoneb9c1b512016-09-06 20:57:50 +0000379
380def run_break_set_by_symbol(
381 test,
382 symbol,
383 extra_options=None,
384 num_expected_locations=-1,
385 sym_exact=False,
386 module_name=None):
Jim Ingham63dfc722012-09-22 00:05:11 +0000387 """Set a breakpoint by symbol name. Common options are the same as run_break_set_by_file_and_line.
388
389 If sym_exact is true, then the output symbol must match the input exactly, otherwise we do a substring match."""
Kate Stoneb9c1b512016-09-06 20:57:50 +0000390 command = 'breakpoint set -n "%s"' % (symbol)
Greg Claytonc1b2ccf2013-01-08 00:01:36 +0000391
392 if module_name:
393 command += " --shlib '%s'" % (module_name)
394
Jim Ingham63dfc722012-09-22 00:05:11 +0000395 if extra_options:
396 command += " " + extra_options
397
Kate Stoneb9c1b512016-09-06 20:57:50 +0000398 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000399
400 if num_expected_locations == 1 and sym_exact:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000401 check_breakpoint_result(
402 test,
403 break_results,
404 num_locations=num_expected_locations,
405 symbol_name=symbol,
406 module_name=module_name)
Jim Ingham63dfc722012-09-22 00:05:11 +0000407 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000408 check_breakpoint_result(
409 test,
410 break_results,
411 num_locations=num_expected_locations)
Jim Ingham63dfc722012-09-22 00:05:11 +0000412
Kate Stoneb9c1b512016-09-06 20:57:50 +0000413 return get_bpno_from_match(break_results)
Jim Ingham63dfc722012-09-22 00:05:11 +0000414
Kate Stoneb9c1b512016-09-06 20:57:50 +0000415
416def run_break_set_by_selector(
417 test,
418 selector,
419 extra_options=None,
420 num_expected_locations=-1,
421 module_name=None):
Jim Ingham63dfc722012-09-22 00:05:11 +0000422 """Set a breakpoint by selector. Common options are the same as run_break_set_by_file_and_line."""
423
Greg Claytonc1b2ccf2013-01-08 00:01:36 +0000424 command = 'breakpoint set -S "%s"' % (selector)
425
426 if module_name:
427 command += ' --shlib "%s"' % (module_name)
428
Jim Ingham63dfc722012-09-22 00:05:11 +0000429 if extra_options:
430 command += " " + extra_options
431
Kate Stoneb9c1b512016-09-06 20:57:50 +0000432 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000433
434 if num_expected_locations == 1:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000435 check_breakpoint_result(
436 test,
437 break_results,
438 num_locations=num_expected_locations,
439 symbol_name=selector,
440 symbol_match_exact=False,
441 module_name=module_name)
Jim Ingham63dfc722012-09-22 00:05:11 +0000442 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000443 check_breakpoint_result(
444 test,
445 break_results,
446 num_locations=num_expected_locations)
Jim Ingham63dfc722012-09-22 00:05:11 +0000447
Kate Stoneb9c1b512016-09-06 20:57:50 +0000448 return get_bpno_from_match(break_results)
Jim Ingham63dfc722012-09-22 00:05:11 +0000449
Kate Stoneb9c1b512016-09-06 20:57:50 +0000450
451def run_break_set_by_regexp(
452 test,
453 regexp,
454 extra_options=None,
455 num_expected_locations=-1):
Jim Ingham63dfc722012-09-22 00:05:11 +0000456 """Set a breakpoint by regular expression match on symbol name. Common options are the same as run_break_set_by_file_and_line."""
457
Kate Stoneb9c1b512016-09-06 20:57:50 +0000458 command = 'breakpoint set -r "%s"' % (regexp)
Jim Ingham63dfc722012-09-22 00:05:11 +0000459 if extra_options:
460 command += " " + extra_options
Jim Ingham63dfc722012-09-22 00:05:11 +0000461
Kate Stoneb9c1b512016-09-06 20:57:50 +0000462 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000463
Kate Stoneb9c1b512016-09-06 20:57:50 +0000464 check_breakpoint_result(
465 test,
466 break_results,
467 num_locations=num_expected_locations)
468
469 return get_bpno_from_match(break_results)
470
471
472def run_break_set_by_source_regexp(
473 test,
474 regexp,
475 extra_options=None,
476 num_expected_locations=-1):
Jim Ingham63dfc722012-09-22 00:05:11 +0000477 """Set a breakpoint by source regular expression. Common options are the same as run_break_set_by_file_and_line."""
Kate Stoneb9c1b512016-09-06 20:57:50 +0000478 command = 'breakpoint set -p "%s"' % (regexp)
Jim Ingham63dfc722012-09-22 00:05:11 +0000479 if extra_options:
480 command += " " + extra_options
Jim Ingham63dfc722012-09-22 00:05:11 +0000481
Kate Stoneb9c1b512016-09-06 20:57:50 +0000482 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000483
Kate Stoneb9c1b512016-09-06 20:57:50 +0000484 check_breakpoint_result(
485 test,
486 break_results,
487 num_locations=num_expected_locations)
488
489 return get_bpno_from_match(break_results)
490
491
492def run_break_set_command(test, command):
493 """Run the command passed in - it must be some break set variant - and analyze the result.
Jim Ingham63dfc722012-09-22 00:05:11 +0000494 Returns a dictionary of information gleaned from the command-line results.
495 Will assert if the breakpoint setting fails altogether.
496
497 Dictionary will contain:
498 bpno - breakpoint of the newly created breakpoint, -1 on error.
499 num_locations - number of locations set for the breakpoint.
500
501 If there is only one location, the dictionary MAY contain:
502 file - source file name
503 line_no - source line number
504 symbol - symbol name
505 inline_symbol - inlined symbol name
506 offset - offset from the original symbol
507 module - module
508 address - address at which the breakpoint was set."""
509
Kate Stoneb9c1b512016-09-06 20:57:50 +0000510 patterns = [
511 r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>[0-9]+) locations\.$",
512 r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>no) locations \(pending\)\.",
513 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]+)$",
514 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]+)$"]
515 match_object = test.match(command, patterns)
Jim Ingham63dfc722012-09-22 00:05:11 +0000516 break_results = match_object.groupdict()
Jim Ingham63dfc722012-09-22 00:05:11 +0000517
518 # We always insert the breakpoint number, setting it to -1 if we couldn't find it
519 # Also, make sure it gets stored as an integer.
520 if not 'bpno' in break_results:
521 break_results['bpno'] = -1
522 else:
523 break_results['bpno'] = int(break_results['bpno'])
Kate Stoneb9c1b512016-09-06 20:57:50 +0000524
Jim Ingham63dfc722012-09-22 00:05:11 +0000525 # We always insert the number of locations
526 # If ONE location is set for the breakpoint, then the output doesn't mention locations, but it has to be 1...
527 # We also make sure it is an integer.
528
529 if not 'num_locations' in break_results:
530 num_locations = 1
531 else:
532 num_locations = break_results['num_locations']
533 if num_locations == 'no':
534 num_locations = 0
535 else:
536 num_locations = int(break_results['num_locations'])
537
538 break_results['num_locations'] = num_locations
Kate Stoneb9c1b512016-09-06 20:57:50 +0000539
Jim Ingham63dfc722012-09-22 00:05:11 +0000540 if 'line_no' in break_results:
541 break_results['line_no'] = int(break_results['line_no'])
542
543 return break_results
544
Jim Ingham63dfc722012-09-22 00:05:11 +0000545
Kate Stoneb9c1b512016-09-06 20:57:50 +0000546def get_bpno_from_match(break_results):
547 return int(break_results['bpno'])
548
549
550def check_breakpoint_result(
551 test,
552 break_results,
553 file_name=None,
554 line_number=-1,
555 symbol_name=None,
556 symbol_match_exact=True,
557 module_name=None,
558 offset=-1,
559 num_locations=-1):
Jim Ingham63dfc722012-09-22 00:05:11 +0000560
561 out_num_locations = break_results['num_locations']
562
Jim Ingham63dfc722012-09-22 00:05:11 +0000563 if num_locations == -1:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000564 test.assertTrue(out_num_locations > 0,
565 "Expecting one or more locations, got none.")
Jim Ingham63dfc722012-09-22 00:05:11 +0000566 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000567 test.assertTrue(
568 num_locations == out_num_locations,
569 "Expecting %d locations, got %d." %
570 (num_locations,
571 out_num_locations))
Jim Ingham63dfc722012-09-22 00:05:11 +0000572
573 if file_name:
574 out_file_name = ""
575 if 'file' in break_results:
576 out_file_name = break_results['file']
Kate Stoneb9c1b512016-09-06 20:57:50 +0000577 test.assertTrue(
578 file_name == out_file_name,
579 "Breakpoint file name '%s' doesn't match resultant name '%s'." %
580 (file_name,
581 out_file_name))
Jim Ingham63dfc722012-09-22 00:05:11 +0000582
583 if line_number != -1:
Ilia K055ad9b2015-05-18 13:41:01 +0000584 out_line_number = -1
Jim Ingham63dfc722012-09-22 00:05:11 +0000585 if 'line_no' in break_results:
586 out_line_number = break_results['line_no']
587
Kate Stoneb9c1b512016-09-06 20:57:50 +0000588 test.assertTrue(
589 line_number == out_line_number,
590 "Breakpoint line number %s doesn't match resultant line %s." %
591 (line_number,
592 out_line_number))
Jim Ingham63dfc722012-09-22 00:05:11 +0000593
594 if symbol_name:
595 out_symbol_name = ""
Kate Stoneb9c1b512016-09-06 20:57:50 +0000596 # Look first for the inlined symbol name, otherwise use the symbol
597 # name:
Jim Ingham63dfc722012-09-22 00:05:11 +0000598 if 'inline_symbol' in break_results and break_results['inline_symbol']:
599 out_symbol_name = break_results['inline_symbol']
600 elif 'symbol' in break_results:
601 out_symbol_name = break_results['symbol']
602
603 if symbol_match_exact:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000604 test.assertTrue(
605 symbol_name == out_symbol_name,
606 "Symbol name '%s' doesn't match resultant symbol '%s'." %
607 (symbol_name,
608 out_symbol_name))
Jim Ingham63dfc722012-09-22 00:05:11 +0000609 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000610 test.assertTrue(
611 out_symbol_name.find(symbol_name) != -
612 1,
613 "Symbol name '%s' isn't in resultant symbol '%s'." %
614 (symbol_name,
615 out_symbol_name))
Jim Ingham63dfc722012-09-22 00:05:11 +0000616
617 if module_name:
Ilia K055ad9b2015-05-18 13:41:01 +0000618 out_module_name = None
Jim Ingham63dfc722012-09-22 00:05:11 +0000619 if 'module' in break_results:
620 out_module_name = break_results['module']
Kate Stoneb9c1b512016-09-06 20:57:50 +0000621
622 test.assertTrue(
623 module_name.find(out_module_name) != -
624 1,
625 "Symbol module name '%s' isn't in expected module name '%s'." %
626 (out_module_name,
627 module_name))
Jim Ingham63dfc722012-09-22 00:05:11 +0000628
629# ==================================================
Johnny Chenf4f70bb2010-10-22 21:31:03 +0000630# Utility functions related to Threads and Processes
631# ==================================================
Johnny Chen28ae2942010-10-07 22:15:58 +0000632
Kate Stoneb9c1b512016-09-06 20:57:50 +0000633
Johnny Chend3699082011-04-25 22:04:05 +0000634def get_stopped_threads(process, reason):
Johnny Chen75ec1592011-05-26 21:53:05 +0000635 """Returns the thread(s) with the specified stop reason in a list.
636
637 The list can be empty if no such thread exists.
638 """
Johnny Chend3699082011-04-25 22:04:05 +0000639 threads = []
Johnny Chene69c7482011-04-28 22:57:01 +0000640 for t in process:
Johnny Chend3699082011-04-25 22:04:05 +0000641 if t.GetStopReason() == reason:
642 threads.append(t)
643 return threads
644
Kate Stoneb9c1b512016-09-06 20:57:50 +0000645
Johnny Chend3699082011-04-25 22:04:05 +0000646def get_stopped_thread(process, reason):
647 """A convenience function which returns the first thread with the given stop
648 reason or None.
649
650 Example usages:
651
652 1. Get the stopped thread due to a breakpoint condition
653
654 ...
655 from lldbutil import get_stopped_thread
Johnny Chen5a0bee72011-06-15 22:14:12 +0000656 thread = get_stopped_thread(process, lldb.eStopReasonPlanComplete)
Greg Clayton53c5ddf2013-03-19 17:59:30 +0000657 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition")
Johnny Chend3699082011-04-25 22:04:05 +0000658 ...
659
660 2. Get the thread stopped due to a breakpoint
661
662 ...
663 from lldbutil import get_stopped_thread
Johnny Chen5a0bee72011-06-15 22:14:12 +0000664 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
Greg Clayton53c5ddf2013-03-19 17:59:30 +0000665 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint")
Johnny Chend3699082011-04-25 22:04:05 +0000666 ...
667
668 """
669 threads = get_stopped_threads(process, reason)
670 if len(threads) == 0:
671 return None
672 return threads[0]
673
Kate Stoneb9c1b512016-09-06 20:57:50 +0000674
Zachary Turner1da094a2016-01-22 23:54:41 +0000675def get_threads_stopped_at_breakpoint_id(process, bpid):
Johnny Chend0fef812011-04-25 23:38:13 +0000676 """ For a stopped process returns the thread stopped at the breakpoint passed in bkpt"""
677 stopped_threads = []
678 threads = []
679
Kate Stoneb9c1b512016-09-06 20:57:50 +0000680 stopped_threads = get_stopped_threads(process, lldb.eStopReasonBreakpoint)
Johnny Chend0fef812011-04-25 23:38:13 +0000681
682 if len(stopped_threads) == 0:
683 return threads
Kate Stoneb9c1b512016-09-06 20:57:50 +0000684
Johnny Chend0fef812011-04-25 23:38:13 +0000685 for thread in stopped_threads:
Johnny Chen32391242011-12-22 20:21:46 +0000686 # Make sure we've hit our breakpoint...
Kate Stoneb9c1b512016-09-06 20:57:50 +0000687 break_id = thread.GetStopReasonDataAtIndex(0)
Zachary Turner1da094a2016-01-22 23:54:41 +0000688 if break_id == bpid:
Johnny Chend0fef812011-04-25 23:38:13 +0000689 threads.append(thread)
690
691 return threads
692
Kate Stoneb9c1b512016-09-06 20:57:50 +0000693
694def get_threads_stopped_at_breakpoint(process, bkpt):
Zachary Turner1da094a2016-01-22 23:54:41 +0000695 return get_threads_stopped_at_breakpoint_id(process, bkpt.GetID())
696
Kate Stoneb9c1b512016-09-06 20:57:50 +0000697
698def get_one_thread_stopped_at_breakpoint_id(
699 process, bpid, require_exactly_one=True):
Zachary Turner1da094a2016-01-22 23:54:41 +0000700 threads = get_threads_stopped_at_breakpoint_id(process, bpid)
Zachary Turner783550b2016-01-21 21:07:30 +0000701 if len(threads) == 0:
702 return None
703 if require_exactly_one and len(threads) != 1:
704 return None
705
706 return threads[0]
707
Zachary Turner1da094a2016-01-22 23:54:41 +0000708
Kate Stoneb9c1b512016-09-06 20:57:50 +0000709def get_one_thread_stopped_at_breakpoint(
710 process, bkpt, require_exactly_one=True):
711 return get_one_thread_stopped_at_breakpoint_id(
712 process, bkpt.GetID(), require_exactly_one)
713
714
715def is_thread_crashed(test, thread):
Pavel Labathc4e25c92015-05-29 10:13:03 +0000716 """In the test suite we dereference a null pointer to simulate a crash. The way this is
717 reported depends on the platform."""
718 if test.platformIsDarwin():
Kate Stoneb9c1b512016-09-06 20:57:50 +0000719 return thread.GetStopReason(
720 ) == lldb.eStopReasonException and "EXC_BAD_ACCESS" in thread.GetStopDescription(100)
Pavel Labathc4e25c92015-05-29 10:13:03 +0000721 elif test.getPlatform() == "linux":
Kate Stoneb9c1b512016-09-06 20:57:50 +0000722 return thread.GetStopReason() == lldb.eStopReasonSignal and thread.GetStopReasonDataAtIndex(
723 0) == thread.GetProcess().GetUnixSignals().GetSignalNumberFromName("SIGSEGV")
Pavel Labathc4e25c92015-05-29 10:13:03 +0000724 else:
725 return "invalid address" in thread.GetStopDescription(100)
726
Kate Stoneb9c1b512016-09-06 20:57:50 +0000727
728def get_crashed_threads(test, process):
Pavel Labathc4e25c92015-05-29 10:13:03 +0000729 threads = []
730 if process.GetState() != lldb.eStateStopped:
731 return threads
732 for thread in process:
733 if is_thread_crashed(test, thread):
734 threads.append(thread)
735 return threads
736
Jim Ingham0423fca2018-02-01 21:35:50 +0000737# Helper functions for run_to_{source,name}_breakpoint:
738
739def run_to_breakpoint_make_target(test, exe_name, in_cwd):
740 if in_cwd:
741 exe = test.getBuildArtifact(exe_name)
742
743 # Create the target
744 target = test.dbg.CreateTarget(exe)
745 test.assertTrue(target, "Target: %s is not valid."%(exe_name))
746 return target
747
748def run_to_breakpoint_do_run(test, target, bkpt, launch_info):
749
750 # Launch the process, and do not stop at the entry point.
751 if not launch_info:
752 launch_info = lldb.SBLaunchInfo(None)
753 launch_info.SetWorkingDirectory(test.get_process_working_directory())
754
755 error = lldb.SBError()
756 process = target.Launch(launch_info, error)
757
758 test.assertTrue(process,
759 "Could not create a valid process for %s: %s"%(target.GetExecutable().GetFilename(),
760 error.GetCString()))
761
762 # Frame #0 should be at our breakpoint.
763 threads = get_threads_stopped_at_breakpoint(
764 process, bkpt)
765
766 test.assertTrue(len(threads) == 1, "Expected 1 thread to stop at breakpoint, %d did."%(len(threads)))
767 thread = threads[0]
768 return (target, process, thread, bkpt)
769
770def run_to_name_breakpoint (test, bkpt_name, launch_info = None,
771 exe_name = "a.out",
Jim Ingham40207d52018-02-02 18:39:25 +0000772 bkpt_module = None,
Jim Ingham0423fca2018-02-01 21:35:50 +0000773 in_cwd = True):
Adrian Prantl595048f2018-01-19 23:24:35 +0000774 """Start up a target, using exe_name as the executable, and run it to
Jim Ingham40207d52018-02-02 18:39:25 +0000775 a breakpoint set by name on bkpt_name restricted to bkpt_module.
Adrian Prantl595048f2018-01-19 23:24:35 +0000776
777 If you want to pass in launch arguments or environment
778 variables, you can optionally pass in an SBLaunchInfo. If you
779 do that, remember to set the working directory as well.
780
781 If your executable isn't called a.out, you can pass that in.
782 And if your executable isn't in the CWD, pass in the absolute
783 path to the executable in exe_name, and set in_cwd to False.
784
Jim Ingham40207d52018-02-02 18:39:25 +0000785 If you need to restrict the breakpoint to a particular module,
786 pass the module name (a string not a FileSpec) in bkpt_module. If
787 nothing is passed in setting will be unrestricted.
788
Jim Inghama15e7f22017-07-06 02:18:16 +0000789 If the target isn't valid, the breakpoint isn't found, or hit, the
790 function will cause a testsuite failure.
Adrian Prantl595048f2018-01-19 23:24:35 +0000791
792 If successful it returns a tuple with the target process and
Jim Ingham40207d52018-02-02 18:39:25 +0000793 thread that hit the breakpoint, and the breakpoint that we set
794 for you.
Adrian Prantl595048f2018-01-19 23:24:35 +0000795 """
Jim Inghama15e7f22017-07-06 02:18:16 +0000796
Jim Ingham0423fca2018-02-01 21:35:50 +0000797 target = run_to_breakpoint_make_target(test, exe_name, in_cwd)
Jim Inghama15e7f22017-07-06 02:18:16 +0000798
Jim Ingham40207d52018-02-02 18:39:25 +0000799 breakpoint = target.BreakpointCreateByName(bkpt_name, bkpt_module)
800
801
Jim Ingham0423fca2018-02-01 21:35:50 +0000802 test.assertTrue(breakpoint.GetNumLocations() > 0,
803 "No locations found for name breakpoint: '%s'."%(bkpt_name))
804 return run_to_breakpoint_do_run(test, target, breakpoint, launch_info)
805
806def run_to_source_breakpoint(test, bkpt_pattern, source_spec,
807 launch_info = None, exe_name = "a.out",
Jim Ingham40207d52018-02-02 18:39:25 +0000808 bkpt_module = None,
Jim Ingham0423fca2018-02-01 21:35:50 +0000809 in_cwd = True):
810 """Start up a target, using exe_name as the executable, and run it to
811 a breakpoint set by source regex bkpt_pattern.
812
813 The rest of the behavior is the same as run_to_name_breakpoint.
814 """
815
816 target = run_to_breakpoint_make_target(test, exe_name, in_cwd)
Jim Inghama15e7f22017-07-06 02:18:16 +0000817 # Set the breakpoints
818 breakpoint = target.BreakpointCreateBySourceRegex(
Jim Ingham40207d52018-02-02 18:39:25 +0000819 bkpt_pattern, source_spec, bkpt_module)
Jim Inghama15e7f22017-07-06 02:18:16 +0000820 test.assertTrue(breakpoint.GetNumLocations() > 0,
Adrian Prantlee2d2bf2018-01-30 19:40:09 +0000821 'No locations found for source breakpoint: "%s", file: "%s", dir: "%s"'%(bkpt_pattern, source_spec.GetFilename(), source_spec.GetDirectory()))
Jim Ingham0423fca2018-02-01 21:35:50 +0000822 return run_to_breakpoint_do_run(test, target, breakpoint, launch_info)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000823
824def continue_to_breakpoint(process, bkpt):
Johnny Chend0fef812011-04-25 23:38:13 +0000825 """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None"""
826 process.Continue()
827 if process.GetState() != lldb.eStateStopped:
828 return None
829 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000830 return get_threads_stopped_at_breakpoint(process, bkpt)
831
Johnny Chend0fef812011-04-25 23:38:13 +0000832
Johnny Chena4603162011-03-09 23:45:56 +0000833def get_caller_symbol(thread):
834 """
835 Returns the symbol name for the call site of the leaf function.
836 """
837 depth = thread.GetNumFrames()
838 if depth <= 1:
839 return None
840 caller = thread.GetFrameAtIndex(1).GetSymbol()
841 if caller:
842 return caller.GetName()
843 else:
844 return None
845
846
Johnny Chend0fef812011-04-25 23:38:13 +0000847def get_function_names(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000848 """
849 Returns a sequence of function names from the stack frames of this thread.
850 """
851 def GetFuncName(i):
Johnny Chen4cfd07e2011-06-20 00:26:39 +0000852 return thread.GetFrameAtIndex(i).GetFunctionName()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000853
Zachary Turner744cd5d2015-10-26 16:49:57 +0000854 return list(map(GetFuncName, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000855
856
Johnny Chend0fef812011-04-25 23:38:13 +0000857def get_symbol_names(thread):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000858 """
859 Returns a sequence of symbols for this thread.
860 """
861 def GetSymbol(i):
862 return thread.GetFrameAtIndex(i).GetSymbol().GetName()
863
Zachary Turner744cd5d2015-10-26 16:49:57 +0000864 return list(map(GetSymbol, list(range(thread.GetNumFrames()))))
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000865
866
Johnny Chend0fef812011-04-25 23:38:13 +0000867def get_pc_addresses(thread):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000868 """
869 Returns a sequence of pc addresses for this thread.
870 """
871 def GetPCAddress(i):
872 return thread.GetFrameAtIndex(i).GetPCAddress()
873
Zachary Turner744cd5d2015-10-26 16:49:57 +0000874 return list(map(GetPCAddress, list(range(thread.GetNumFrames()))))
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000875
876
Johnny Chend0fef812011-04-25 23:38:13 +0000877def get_filenames(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000878 """
879 Returns a sequence of file names from the stack frames of this thread.
880 """
881 def GetFilename(i):
Kate Stoneb9c1b512016-09-06 20:57:50 +0000882 return thread.GetFrameAtIndex(
883 i).GetLineEntry().GetFileSpec().GetFilename()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000884
Zachary Turner744cd5d2015-10-26 16:49:57 +0000885 return list(map(GetFilename, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000886
887
Johnny Chend0fef812011-04-25 23:38:13 +0000888def get_line_numbers(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000889 """
890 Returns a sequence of line numbers from the stack frames of this thread.
891 """
892 def GetLineNumber(i):
893 return thread.GetFrameAtIndex(i).GetLineEntry().GetLine()
894
Zachary Turner744cd5d2015-10-26 16:49:57 +0000895 return list(map(GetLineNumber, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000896
897
Johnny Chend0fef812011-04-25 23:38:13 +0000898def get_module_names(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000899 """
900 Returns a sequence of module names from the stack frames of this thread.
901 """
902 def GetModuleName(i):
Kate Stoneb9c1b512016-09-06 20:57:50 +0000903 return thread.GetFrameAtIndex(
904 i).GetModule().GetFileSpec().GetFilename()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000905
Zachary Turner744cd5d2015-10-26 16:49:57 +0000906 return list(map(GetModuleName, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000907
908
Johnny Chend0fef812011-04-25 23:38:13 +0000909def get_stack_frames(thread):
Johnny Chen43a651c2010-09-09 00:55:07 +0000910 """
911 Returns a sequence of stack frames for this thread.
912 """
913 def GetStackFrame(i):
914 return thread.GetFrameAtIndex(i)
915
Zachary Turner744cd5d2015-10-26 16:49:57 +0000916 return list(map(GetStackFrame, list(range(thread.GetNumFrames()))))
Johnny Chen43a651c2010-09-09 00:55:07 +0000917
918
Kate Stoneb9c1b512016-09-06 20:57:50 +0000919def print_stacktrace(thread, string_buffer=False):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000920 """Prints a simple stack trace of this thread."""
Johnny Chen6c704992010-10-07 18:52:48 +0000921
Zachary Turner814236d2015-10-21 17:48:52 +0000922 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000923 target = thread.GetProcess().GetTarget()
924
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000925 depth = thread.GetNumFrames()
926
Johnny Chend0fef812011-04-25 23:38:13 +0000927 mods = get_module_names(thread)
928 funcs = get_function_names(thread)
929 symbols = get_symbol_names(thread)
930 files = get_filenames(thread)
931 lines = get_line_numbers(thread)
932 addrs = get_pc_addresses(thread)
Johnny Chen6c704992010-10-07 18:52:48 +0000933
Johnny Chen567a0452010-10-25 19:13:52 +0000934 if thread.GetStopReason() != lldb.eStopReasonInvalid:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000935 desc = "stop reason=" + stop_reason_to_str(thread.GetStopReason())
Johnny Chen567a0452010-10-25 19:13:52 +0000936 else:
937 desc = ""
Kate Stoneb9c1b512016-09-06 20:57:50 +0000938 print(
939 "Stack trace for thread id={0:#x} name={1} queue={2} ".format(
940 thread.GetThreadID(),
941 thread.GetName(),
942 thread.GetQueueName()) + desc,
943 file=output)
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000944
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000945 for i in range(depth):
946 frame = thread.GetFrameAtIndex(i)
947 function = frame.GetFunction()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000948
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000949 load_addr = addrs[i].GetLoadAddress(target)
Johnny Chen3cd1e552011-05-25 19:06:18 +0000950 if not function:
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000951 file_addr = addrs[i].GetFileAddress()
Johnny Chen0d4f6dd2011-06-16 22:07:48 +0000952 start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress()
953 symbol_offset = file_addr - start_addr
Kate Stoneb9c1b512016-09-06 20:57:50 +0000954 print(
955 " frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format(
956 num=i,
957 addr=load_addr,
958 mod=mods[i],
959 symbol=symbols[i],
960 offset=symbol_offset),
961 file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000962 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000963 print(
964 " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format(
965 num=i,
966 addr=load_addr,
967 mod=mods[i],
968 func='%s [inlined]' %
969 funcs[i] if frame.IsInlined() else funcs[i],
970 file=files[i],
971 line=lines[i],
972 args=get_args_as_string(
973 frame,
974 showFuncName=False) if not frame.IsInlined() else '()'),
975 file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000976
977 if string_buffer:
Johnny Chend5d6fac2010-10-15 23:33:18 +0000978 return output.getvalue()
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000979
980
Kate Stoneb9c1b512016-09-06 20:57:50 +0000981def print_stacktraces(process, string_buffer=False):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000982 """Prints the stack traces of all the threads."""
983
Zachary Turner814236d2015-10-21 17:48:52 +0000984 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000985
Zachary Turnerff890da2015-10-19 23:45:41 +0000986 print("Stack traces for " + str(process), file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000987
Johnny Chenae9639a2011-05-05 18:50:56 +0000988 for thread in process:
Zachary Turnerff890da2015-10-19 23:45:41 +0000989 print(print_stacktrace(thread, string_buffer=True), file=output)
Johnny Chen6c704992010-10-07 18:52:48 +0000990
991 if string_buffer:
Johnny Chend5d6fac2010-10-15 23:33:18 +0000992 return output.getvalue()
Johnny Chenb21c52e2011-05-08 17:25:27 +0000993
Kate Stoneb9c1b512016-09-06 20:57:50 +0000994
995def expect_state_changes(test, listener, process, states, timeout=5):
Pavel Labath5dcb0252015-09-02 09:12:28 +0000996 """Listens for state changed events on the listener and makes sure they match what we
997 expect. Stop-and-restart events (where GetRestartedFromEvent() returns true) are ignored."""
Pavel Labathe5c98082016-01-06 11:40:06 +0000998
Pavel Labath5dcb0252015-09-02 09:12:28 +0000999 for expected_state in states:
Pavel Labathe5c98082016-01-06 11:40:06 +00001000 def get_next_event():
1001 event = lldb.SBEvent()
Kate Stoneb9c1b512016-09-06 20:57:50 +00001002 if not listener.WaitForEventForBroadcasterWithType(
1003 timeout,
1004 process.GetBroadcaster(),
1005 lldb.SBProcess.eBroadcastBitStateChanged,
1006 event):
1007 test.fail(
1008 "Timed out while waiting for a transition to state %s" %
Pavel Labathe5c98082016-01-06 11:40:06 +00001009 lldb.SBDebugger.StateAsCString(expected_state))
1010 return event
Pavel Labath5dcb0252015-09-02 09:12:28 +00001011
Pavel Labathe5c98082016-01-06 11:40:06 +00001012 event = get_next_event()
1013 while (lldb.SBProcess.GetStateFromEvent(event) == lldb.eStateStopped and
1014 lldb.SBProcess.GetRestartedFromEvent(event)):
1015 # Ignore restarted event and the subsequent running event.
1016 event = get_next_event()
Kate Stoneb9c1b512016-09-06 20:57:50 +00001017 test.assertEqual(
1018 lldb.SBProcess.GetStateFromEvent(event),
1019 lldb.eStateRunning,
1020 "Restarted event followed by a running event")
Pavel Labathe5c98082016-01-06 11:40:06 +00001021 event = get_next_event()
Pavel Labath5dcb0252015-09-02 09:12:28 +00001022
Kate Stoneb9c1b512016-09-06 20:57:50 +00001023 test.assertEqual(
1024 lldb.SBProcess.GetStateFromEvent(event),
1025 expected_state)
Pavel Labath5dcb0252015-09-02 09:12:28 +00001026
Johnny Chenb21c52e2011-05-08 17:25:27 +00001027# ===================================
1028# Utility functions related to Frames
1029# ===================================
1030
Kate Stoneb9c1b512016-09-06 20:57:50 +00001031
Johnny Chenad7372c2011-05-12 00:32:41 +00001032def get_parent_frame(frame):
1033 """
1034 Returns the parent frame of the input frame object; None if not available.
1035 """
1036 thread = frame.GetThread()
1037 parent_found = False
1038 for f in thread:
1039 if parent_found:
1040 return f
1041 if f.GetFrameID() == frame.GetFrameID():
1042 parent_found = True
1043
1044 # If we reach here, no parent has been found, return None.
1045 return None
1046
Kate Stoneb9c1b512016-09-06 20:57:50 +00001047
Johnny Chen0d4f6dd2011-06-16 22:07:48 +00001048def get_args_as_string(frame, showFuncName=True):
Johnny Chenad7372c2011-05-12 00:32:41 +00001049 """
1050 Returns the args of the input frame object as a string.
1051 """
1052 # arguments => True
1053 # locals => False
1054 # statics => False
1055 # in_scope_only => True
Kate Stoneb9c1b512016-09-06 20:57:50 +00001056 vars = frame.GetVariables(True, False, False, True) # type of SBValueList
1057 args = [] # list of strings
Johnny Chenad7372c2011-05-12 00:32:41 +00001058 for var in vars:
1059 args.append("(%s)%s=%s" % (var.GetTypeName(),
1060 var.GetName(),
Greg Claytonfe42ac42011-08-03 22:57:10 +00001061 var.GetValue()))
Johnny Chen3cd1e552011-05-25 19:06:18 +00001062 if frame.GetFunction():
Johnny Chen52b0ffd92011-05-13 00:44:49 +00001063 name = frame.GetFunction().GetName()
Johnny Chen3cd1e552011-05-25 19:06:18 +00001064 elif frame.GetSymbol():
Johnny Chen52b0ffd92011-05-13 00:44:49 +00001065 name = frame.GetSymbol().GetName()
1066 else:
1067 name = ""
Johnny Chen0d4f6dd2011-06-16 22:07:48 +00001068 if showFuncName:
1069 return "%s(%s)" % (name, ", ".join(args))
1070 else:
1071 return "(%s)" % (", ".join(args))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001072
1073
1074def print_registers(frame, string_buffer=False):
Johnny Chen2158b972011-05-08 18:55:37 +00001075 """Prints all the register sets of the frame."""
Johnny Chenb21c52e2011-05-08 17:25:27 +00001076
Zachary Turner814236d2015-10-21 17:48:52 +00001077 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chenb21c52e2011-05-08 17:25:27 +00001078
Zachary Turnerff890da2015-10-19 23:45:41 +00001079 print("Register sets for " + str(frame), file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +00001080
Kate Stoneb9c1b512016-09-06 20:57:50 +00001081 registerSet = frame.GetRegisters() # Return type of SBValueList.
1082 print("Frame registers (size of register set = %d):" %
1083 registerSet.GetSize(), file=output)
Johnny Chen64ff7e62011-05-10 19:21:13 +00001084 for value in registerSet:
Zachary Turner35d017f2015-10-23 17:04:29 +00001085 #print(value, file=output)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001086 print("%s (number of children = %d):" %
1087 (value.GetName(), value.GetNumChildren()), file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +00001088 for child in value:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001089 print(
1090 "Name: %s, Value: %s" %
1091 (child.GetName(),
1092 child.GetValue()),
1093 file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +00001094
1095 if string_buffer:
1096 return output.getvalue()
Johnny Chen64ff7e62011-05-10 19:21:13 +00001097
Kate Stoneb9c1b512016-09-06 20:57:50 +00001098
Johnny Chen64ff7e62011-05-10 19:21:13 +00001099def get_registers(frame, kind):
1100 """Returns the registers given the frame and the kind of registers desired.
1101
1102 Returns None if there's no such kind.
1103 """
Kate Stoneb9c1b512016-09-06 20:57:50 +00001104 registerSet = frame.GetRegisters() # Return type of SBValueList.
Johnny Chen64ff7e62011-05-10 19:21:13 +00001105 for value in registerSet:
1106 if kind.lower() in value.GetName().lower():
1107 return value
1108
1109 return None
1110
Kate Stoneb9c1b512016-09-06 20:57:50 +00001111
Johnny Chen64ff7e62011-05-10 19:21:13 +00001112def get_GPRs(frame):
1113 """Returns the general purpose registers of the frame as an SBValue.
1114
Johnny Chene9e86892011-05-10 23:01:44 +00001115 The returned SBValue object is iterable. An example:
1116 ...
1117 from lldbutil import get_GPRs
1118 regs = get_GPRs(frame)
1119 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +00001120 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +00001121 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +00001122 """
1123 return get_registers(frame, "general purpose")
1124
Kate Stoneb9c1b512016-09-06 20:57:50 +00001125
Johnny Chen64ff7e62011-05-10 19:21:13 +00001126def get_FPRs(frame):
1127 """Returns the floating point registers of the frame as an SBValue.
1128
Johnny Chene9e86892011-05-10 23:01:44 +00001129 The returned SBValue object is iterable. An example:
1130 ...
1131 from lldbutil import get_FPRs
1132 regs = get_FPRs(frame)
1133 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +00001134 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +00001135 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +00001136 """
1137 return get_registers(frame, "floating point")
1138
Kate Stoneb9c1b512016-09-06 20:57:50 +00001139
Johnny Chen64ff7e62011-05-10 19:21:13 +00001140def get_ESRs(frame):
1141 """Returns the exception state registers of the frame as an SBValue.
1142
Johnny Chene9e86892011-05-10 23:01:44 +00001143 The returned SBValue object is iterable. An example:
1144 ...
1145 from lldbutil import get_ESRs
1146 regs = get_ESRs(frame)
1147 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +00001148 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +00001149 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +00001150 """
1151 return get_registers(frame, "exception state")
Johnny Chen989b7ef2011-07-22 00:47:58 +00001152
Johnny Chenefee1cd2011-07-22 00:51:54 +00001153# ======================================
1154# Utility classes/functions for SBValues
1155# ======================================
Johnny Chen989b7ef2011-07-22 00:47:58 +00001156
Kate Stoneb9c1b512016-09-06 20:57:50 +00001157
Johnny Chen989b7ef2011-07-22 00:47:58 +00001158class BasicFormatter(object):
Johnny Chen36d7d912011-07-22 22:01:35 +00001159 """The basic formatter inspects the value object and prints the value."""
Kate Stoneb9c1b512016-09-06 20:57:50 +00001160
Johnny Chen989b7ef2011-07-22 00:47:58 +00001161 def format(self, value, buffer=None, indent=0):
1162 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +00001163 output = SixStringIO()
Johnny Chen989b7ef2011-07-22 00:47:58 +00001164 else:
1165 output = buffer
Johnny Chen36d7d912011-07-22 22:01:35 +00001166 # If there is a summary, it suffices.
1167 val = value.GetSummary()
1168 # Otherwise, get the value.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001169 if val is None:
Johnny Chen36d7d912011-07-22 22:01:35 +00001170 val = value.GetValue()
Kate Stoneb9c1b512016-09-06 20:57:50 +00001171 if val is None and value.GetNumChildren() > 0:
Johnny Chen36d7d912011-07-22 22:01:35 +00001172 val = "%s (location)" % value.GetLocation()
Zachary Turnerff890da2015-10-19 23:45:41 +00001173 print("{indentation}({type}) {name} = {value}".format(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001174 indentation=' ' * indent,
1175 type=value.GetTypeName(),
1176 name=value.GetName(),
1177 value=val), file=output)
Johnny Chen989b7ef2011-07-22 00:47:58 +00001178 return output.getvalue()
1179
Kate Stoneb9c1b512016-09-06 20:57:50 +00001180
Johnny Chen989b7ef2011-07-22 00:47:58 +00001181class ChildVisitingFormatter(BasicFormatter):
Johnny Chen36d7d912011-07-22 22:01:35 +00001182 """The child visiting formatter prints the value and its immediate children.
1183
1184 The constructor takes a keyword arg: indent_child, which defaults to 2.
1185 """
Kate Stoneb9c1b512016-09-06 20:57:50 +00001186
Johnny Chen36d7d912011-07-22 22:01:35 +00001187 def __init__(self, indent_child=2):
1188 """Default indentation of 2 SPC's for the children."""
1189 self.cindent = indent_child
Kate Stoneb9c1b512016-09-06 20:57:50 +00001190
Johnny Chen989b7ef2011-07-22 00:47:58 +00001191 def format(self, value, buffer=None):
1192 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +00001193 output = SixStringIO()
Johnny Chen989b7ef2011-07-22 00:47:58 +00001194 else:
1195 output = buffer
1196
1197 BasicFormatter.format(self, value, buffer=output)
1198 for child in value:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001199 BasicFormatter.format(
1200 self, child, buffer=output, indent=self.cindent)
Johnny Chen36d7d912011-07-22 22:01:35 +00001201
1202 return output.getvalue()
1203
Kate Stoneb9c1b512016-09-06 20:57:50 +00001204
Johnny Chen36d7d912011-07-22 22:01:35 +00001205class RecursiveDecentFormatter(BasicFormatter):
1206 """The recursive decent formatter prints the value and the decendents.
1207
1208 The constructor takes two keyword args: indent_level, which defaults to 0,
1209 and indent_child, which defaults to 2. The current indentation level is
1210 determined by indent_level, while the immediate children has an additional
Kate Stoneb9c1b512016-09-06 20:57:50 +00001211 indentation by inden_child.
Johnny Chen36d7d912011-07-22 22:01:35 +00001212 """
Kate Stoneb9c1b512016-09-06 20:57:50 +00001213
Johnny Chen36d7d912011-07-22 22:01:35 +00001214 def __init__(self, indent_level=0, indent_child=2):
1215 self.lindent = indent_level
1216 self.cindent = indent_child
Kate Stoneb9c1b512016-09-06 20:57:50 +00001217
Johnny Chen36d7d912011-07-22 22:01:35 +00001218 def format(self, value, buffer=None):
1219 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +00001220 output = SixStringIO()
Johnny Chen36d7d912011-07-22 22:01:35 +00001221 else:
1222 output = buffer
1223
1224 BasicFormatter.format(self, value, buffer=output, indent=self.lindent)
1225 new_indent = self.lindent + self.cindent
1226 for child in value:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001227 if child.GetSummary() is not None:
1228 BasicFormatter.format(
1229 self, child, buffer=output, indent=new_indent)
Johnny Chen36d7d912011-07-22 22:01:35 +00001230 else:
1231 if child.GetNumChildren() > 0:
1232 rdf = RecursiveDecentFormatter(indent_level=new_indent)
1233 rdf.format(child, buffer=output)
1234 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001235 BasicFormatter.format(
1236 self, child, buffer=output, indent=new_indent)
Johnny Chen989b7ef2011-07-22 00:47:58 +00001237
1238 return output.getvalue()
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001239
1240# ===========================================================
1241# Utility functions for path manipulation on remote platforms
1242# ===========================================================
1243
Kate Stoneb9c1b512016-09-06 20:57:50 +00001244
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001245def join_remote_paths(*paths):
1246 # TODO: update with actual platform name for remote windows once it exists
1247 if lldb.remote_platform.GetName() == 'remote-windows':
1248 return os.path.join(*paths).replace(os.path.sep, '\\')
1249 return os.path.join(*paths).replace(os.path.sep, '/')
1250
Kate Stoneb9c1b512016-09-06 20:57:50 +00001251
Chaoren Lin5d76b1b2015-06-06 00:25:50 +00001252def append_to_process_working_directory(*paths):
1253 remote = lldb.remote_platform
1254 if remote:
1255 return join_remote_paths(remote.GetWorkingDirectory(), *paths)
1256 return os.path.join(os.getcwd(), *paths)
Chaoren Linf59d05092015-06-02 16:46:28 +00001257
1258# ==================================================
1259# Utility functions to get the correct signal number
1260# ==================================================
1261
1262import signal
1263
Kate Stoneb9c1b512016-09-06 20:57:50 +00001264
Chaoren Linf59d05092015-06-02 16:46:28 +00001265def get_signal_number(signal_name):
1266 platform = lldb.remote_platform
Chaoren Lin98d0a4b2015-07-14 01:09:28 +00001267 if platform and platform.IsValid():
1268 signals = platform.GetUnixSignals()
1269 if signals.IsValid():
Chaoren Lin264e5422015-06-02 18:31:57 +00001270 signal_number = signals.GetSignalNumberFromName(signal_name)
1271 if signal_number > 0:
1272 return signal_number
Chaoren Lin98d0a4b2015-07-14 01:09:28 +00001273 # No remote platform; fall back to using local python signals.
Chaoren Linf59d05092015-06-02 16:46:28 +00001274 return getattr(signal, signal_name)
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001275
Kate Stoneb9c1b512016-09-06 20:57:50 +00001276
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001277class PrintableRegex(object):
Kate Stoneb9c1b512016-09-06 20:57:50 +00001278
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001279 def __init__(self, text):
1280 self.regex = re.compile(text)
1281 self.text = text
Kate Stoneb9c1b512016-09-06 20:57:50 +00001282
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001283 def match(self, str):
1284 return self.regex.match(str)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001285
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001286 def __str__(self):
1287 return "%s" % (self.text)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001288
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001289 def __repr__(self):
1290 return "re.compile(%s) -> %s" % (self.text, self.regex)
1291
Kate Stoneb9c1b512016-09-06 20:57:50 +00001292
Enrico Granataef4fa442015-12-04 19:50:05 +00001293def skip_if_callable(test, mycallable, reason):
1294 if six.callable(mycallable):
1295 if mycallable(test):
1296 test.skipTest(reason)
1297 return True
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001298 return False
1299
Kate Stoneb9c1b512016-09-06 20:57:50 +00001300
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001301def skip_if_library_missing(test, target, library):
1302 def find_library(target, library):
1303 for module in target.modules:
1304 filename = module.file.GetFilename()
1305 if isinstance(library, str):
1306 if library == filename:
1307 return False
1308 elif hasattr(library, 'match'):
1309 if library.match(filename):
1310 return False
1311 return True
Kate Stoneb9c1b512016-09-06 20:57:50 +00001312
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001313 def find_library_callable(test):
1314 return find_library(target, library)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001315 return skip_if_callable(
1316 test,
1317 find_library_callable,
1318 "could not find library matching '%s' in target %s" %
1319 (library,
1320 target))
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001321
Kate Stoneb9c1b512016-09-06 20:57:50 +00001322
1323def wait_for_file_on_target(testcase, file_path, max_attempts=6):
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001324 for i in range(max_attempts):
1325 err, retcode, msg = testcase.run_platform_command("ls %s" % file_path)
1326 if err.Success() and retcode == 0:
1327 break
1328 if i < max_attempts:
1329 # Exponential backoff!
Todd Fiala464f7df2016-04-08 18:06:11 +00001330 import time
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001331 time.sleep(pow(2, i) * 0.25)
1332 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001333 testcase.fail(
1334 "File %s not found even after %d attempts." %
1335 (file_path, max_attempts))
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001336
1337 err, retcode, data = testcase.run_platform_command("cat %s" % (file_path))
1338
Kate Stoneb9c1b512016-09-06 20:57:50 +00001339 testcase.assertTrue(
1340 err.Success() and retcode == 0, "Failed to read file %s: %s, retcode: %d" %
1341 (file_path, err.GetCString(), retcode))
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001342 return data