blob: d8dd67653e12143d6283d9f784198e837f3d6920 [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
Jim Ingham3815e702018-09-13 21:35:32 +0000333def run_break_set_by_script(
334 test,
335 class_name,
336 extra_options=None,
337 num_expected_locations=1):
338 """Set a scripted breakpoint. Check that it got the right number of locations."""
339 test.assertTrue(class_name is not None, "Must pass in a class name.")
340 command = "breakpoint set -P " + class_name
341 if extra_options is not None:
342 command += " " + extra_options
343
344 break_results = run_break_set_command(test, command)
345 check_breakpoint_result(test, break_results, num_locations=num_expected_locations)
346 return get_bpno_from_match(break_results)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000347
348def run_break_set_by_file_and_line(
349 test,
350 file_name,
351 line_number,
352 extra_options=None,
353 num_expected_locations=1,
354 loc_exact=False,
355 module_name=None):
356 """Set a breakpoint by file and line, returning the breakpoint number.
Jim Ingham63dfc722012-09-22 00:05:11 +0000357
358 If extra_options is not None, then we append it to the breakpoint set command.
359
Adrian McCarthy25727a42018-02-21 18:08:23 +0000360 If num_expected_locations is -1, we check that we got AT LEAST one location. If num_expected_locations is -2, we don't
361 check the actual number at all. Otherwise, we check that num_expected_locations equals the number of locations.
Jim Ingham63dfc722012-09-22 00:05:11 +0000362
363 If loc_exact is true, we check that there is one location, and that location must be at the input file and line number."""
364
Kate Stoneb9c1b512016-09-06 20:57:50 +0000365 if file_name is None:
366 command = 'breakpoint set -l %d' % (line_number)
Jim Ingham63dfc722012-09-22 00:05:11 +0000367 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000368 command = 'breakpoint set -f "%s" -l %d' % (file_name, line_number)
Jim Ingham63dfc722012-09-22 00:05:11 +0000369
Greg Claytonc1b2ccf2013-01-08 00:01:36 +0000370 if module_name:
371 command += " --shlib '%s'" % (module_name)
372
Jim Ingham63dfc722012-09-22 00:05:11 +0000373 if extra_options:
374 command += " " + extra_options
375
Kate Stoneb9c1b512016-09-06 20:57:50 +0000376 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000377
378 if num_expected_locations == 1 and loc_exact:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000379 check_breakpoint_result(
380 test,
381 break_results,
382 num_locations=num_expected_locations,
383 file_name=file_name,
384 line_number=line_number,
385 module_name=module_name)
Jim Ingham63dfc722012-09-22 00:05:11 +0000386 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000387 check_breakpoint_result(
388 test,
389 break_results,
390 num_locations=num_expected_locations)
Jim Ingham63dfc722012-09-22 00:05:11 +0000391
Kate Stoneb9c1b512016-09-06 20:57:50 +0000392 return get_bpno_from_match(break_results)
Jim Ingham63dfc722012-09-22 00:05:11 +0000393
Kate Stoneb9c1b512016-09-06 20:57:50 +0000394
395def run_break_set_by_symbol(
396 test,
397 symbol,
398 extra_options=None,
399 num_expected_locations=-1,
400 sym_exact=False,
401 module_name=None):
Jim Ingham63dfc722012-09-22 00:05:11 +0000402 """Set a breakpoint by symbol name. Common options are the same as run_break_set_by_file_and_line.
403
404 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 +0000405 command = 'breakpoint set -n "%s"' % (symbol)
Greg Claytonc1b2ccf2013-01-08 00:01:36 +0000406
407 if module_name:
408 command += " --shlib '%s'" % (module_name)
409
Jim Ingham63dfc722012-09-22 00:05:11 +0000410 if extra_options:
411 command += " " + extra_options
412
Kate Stoneb9c1b512016-09-06 20:57:50 +0000413 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000414
415 if num_expected_locations == 1 and sym_exact:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000416 check_breakpoint_result(
417 test,
418 break_results,
419 num_locations=num_expected_locations,
420 symbol_name=symbol,
421 module_name=module_name)
Jim Ingham63dfc722012-09-22 00:05:11 +0000422 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000423 check_breakpoint_result(
424 test,
425 break_results,
426 num_locations=num_expected_locations)
Jim Ingham63dfc722012-09-22 00:05:11 +0000427
Kate Stoneb9c1b512016-09-06 20:57:50 +0000428 return get_bpno_from_match(break_results)
Jim Ingham63dfc722012-09-22 00:05:11 +0000429
Kate Stoneb9c1b512016-09-06 20:57:50 +0000430
431def run_break_set_by_selector(
432 test,
433 selector,
434 extra_options=None,
435 num_expected_locations=-1,
436 module_name=None):
Jim Ingham63dfc722012-09-22 00:05:11 +0000437 """Set a breakpoint by selector. Common options are the same as run_break_set_by_file_and_line."""
438
Greg Claytonc1b2ccf2013-01-08 00:01:36 +0000439 command = 'breakpoint set -S "%s"' % (selector)
440
441 if module_name:
442 command += ' --shlib "%s"' % (module_name)
443
Jim Ingham63dfc722012-09-22 00:05:11 +0000444 if extra_options:
445 command += " " + extra_options
446
Kate Stoneb9c1b512016-09-06 20:57:50 +0000447 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000448
449 if num_expected_locations == 1:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000450 check_breakpoint_result(
451 test,
452 break_results,
453 num_locations=num_expected_locations,
454 symbol_name=selector,
455 symbol_match_exact=False,
456 module_name=module_name)
Jim Ingham63dfc722012-09-22 00:05:11 +0000457 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000458 check_breakpoint_result(
459 test,
460 break_results,
461 num_locations=num_expected_locations)
Jim Ingham63dfc722012-09-22 00:05:11 +0000462
Kate Stoneb9c1b512016-09-06 20:57:50 +0000463 return get_bpno_from_match(break_results)
Jim Ingham63dfc722012-09-22 00:05:11 +0000464
Kate Stoneb9c1b512016-09-06 20:57:50 +0000465
466def run_break_set_by_regexp(
467 test,
468 regexp,
469 extra_options=None,
470 num_expected_locations=-1):
Jim Ingham63dfc722012-09-22 00:05:11 +0000471 """Set a breakpoint by regular expression match on symbol name. Common options are the same as run_break_set_by_file_and_line."""
472
Kate Stoneb9c1b512016-09-06 20:57:50 +0000473 command = 'breakpoint set -r "%s"' % (regexp)
Jim Ingham63dfc722012-09-22 00:05:11 +0000474 if extra_options:
475 command += " " + extra_options
Jim Ingham63dfc722012-09-22 00:05:11 +0000476
Kate Stoneb9c1b512016-09-06 20:57:50 +0000477 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000478
Kate Stoneb9c1b512016-09-06 20:57:50 +0000479 check_breakpoint_result(
480 test,
481 break_results,
482 num_locations=num_expected_locations)
483
484 return get_bpno_from_match(break_results)
485
486
487def run_break_set_by_source_regexp(
488 test,
489 regexp,
490 extra_options=None,
491 num_expected_locations=-1):
Jim Ingham63dfc722012-09-22 00:05:11 +0000492 """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 +0000493 command = 'breakpoint set -p "%s"' % (regexp)
Jim Ingham63dfc722012-09-22 00:05:11 +0000494 if extra_options:
495 command += " " + extra_options
Jim Ingham63dfc722012-09-22 00:05:11 +0000496
Kate Stoneb9c1b512016-09-06 20:57:50 +0000497 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000498
Kate Stoneb9c1b512016-09-06 20:57:50 +0000499 check_breakpoint_result(
500 test,
501 break_results,
502 num_locations=num_expected_locations)
503
504 return get_bpno_from_match(break_results)
505
506
507def run_break_set_command(test, command):
508 """Run the command passed in - it must be some break set variant - and analyze the result.
Jim Ingham63dfc722012-09-22 00:05:11 +0000509 Returns a dictionary of information gleaned from the command-line results.
510 Will assert if the breakpoint setting fails altogether.
511
512 Dictionary will contain:
513 bpno - breakpoint of the newly created breakpoint, -1 on error.
514 num_locations - number of locations set for the breakpoint.
515
516 If there is only one location, the dictionary MAY contain:
517 file - source file name
518 line_no - source line number
519 symbol - symbol name
520 inline_symbol - inlined symbol name
521 offset - offset from the original symbol
522 module - module
523 address - address at which the breakpoint was set."""
524
Kate Stoneb9c1b512016-09-06 20:57:50 +0000525 patterns = [
526 r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>[0-9]+) locations\.$",
527 r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>no) locations \(pending\)\.",
Adrian Prantl431b1582018-08-30 15:11:00 +0000528 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]+)(?P<column>(:[0-9]+)?), address = (?P<address>0x[0-9a-fA-F]+)$",
Kate Stoneb9c1b512016-09-06 20:57:50 +0000529 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]+)$"]
530 match_object = test.match(command, patterns)
Jim Ingham63dfc722012-09-22 00:05:11 +0000531 break_results = match_object.groupdict()
Jim Ingham63dfc722012-09-22 00:05:11 +0000532
533 # We always insert the breakpoint number, setting it to -1 if we couldn't find it
534 # Also, make sure it gets stored as an integer.
535 if not 'bpno' in break_results:
536 break_results['bpno'] = -1
537 else:
538 break_results['bpno'] = int(break_results['bpno'])
Kate Stoneb9c1b512016-09-06 20:57:50 +0000539
Jim Ingham63dfc722012-09-22 00:05:11 +0000540 # We always insert the number of locations
541 # If ONE location is set for the breakpoint, then the output doesn't mention locations, but it has to be 1...
542 # We also make sure it is an integer.
543
544 if not 'num_locations' in break_results:
545 num_locations = 1
546 else:
547 num_locations = break_results['num_locations']
548 if num_locations == 'no':
549 num_locations = 0
550 else:
551 num_locations = int(break_results['num_locations'])
552
553 break_results['num_locations'] = num_locations
Kate Stoneb9c1b512016-09-06 20:57:50 +0000554
Jim Ingham63dfc722012-09-22 00:05:11 +0000555 if 'line_no' in break_results:
556 break_results['line_no'] = int(break_results['line_no'])
557
558 return break_results
559
Jim Ingham63dfc722012-09-22 00:05:11 +0000560
Kate Stoneb9c1b512016-09-06 20:57:50 +0000561def get_bpno_from_match(break_results):
562 return int(break_results['bpno'])
563
564
565def check_breakpoint_result(
566 test,
567 break_results,
568 file_name=None,
569 line_number=-1,
570 symbol_name=None,
571 symbol_match_exact=True,
572 module_name=None,
573 offset=-1,
574 num_locations=-1):
Jim Ingham63dfc722012-09-22 00:05:11 +0000575
576 out_num_locations = break_results['num_locations']
577
Jim Ingham63dfc722012-09-22 00:05:11 +0000578 if num_locations == -1:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000579 test.assertTrue(out_num_locations > 0,
580 "Expecting one or more locations, got none.")
Adrian McCarthy25727a42018-02-21 18:08:23 +0000581 elif num_locations != -2:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000582 test.assertTrue(
583 num_locations == out_num_locations,
584 "Expecting %d locations, got %d." %
585 (num_locations,
586 out_num_locations))
Jim Ingham63dfc722012-09-22 00:05:11 +0000587
588 if file_name:
589 out_file_name = ""
590 if 'file' in break_results:
591 out_file_name = break_results['file']
Kate Stoneb9c1b512016-09-06 20:57:50 +0000592 test.assertTrue(
Greg Clayton52098cf2018-04-13 14:52:54 +0000593 file_name.endswith(out_file_name),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000594 "Breakpoint file name '%s' doesn't match resultant name '%s'." %
595 (file_name,
596 out_file_name))
Jim Ingham63dfc722012-09-22 00:05:11 +0000597
598 if line_number != -1:
Ilia K055ad9b2015-05-18 13:41:01 +0000599 out_line_number = -1
Jim Ingham63dfc722012-09-22 00:05:11 +0000600 if 'line_no' in break_results:
601 out_line_number = break_results['line_no']
602
Kate Stoneb9c1b512016-09-06 20:57:50 +0000603 test.assertTrue(
604 line_number == out_line_number,
605 "Breakpoint line number %s doesn't match resultant line %s." %
606 (line_number,
607 out_line_number))
Jim Ingham63dfc722012-09-22 00:05:11 +0000608
609 if symbol_name:
610 out_symbol_name = ""
Kate Stoneb9c1b512016-09-06 20:57:50 +0000611 # Look first for the inlined symbol name, otherwise use the symbol
612 # name:
Jim Ingham63dfc722012-09-22 00:05:11 +0000613 if 'inline_symbol' in break_results and break_results['inline_symbol']:
614 out_symbol_name = break_results['inline_symbol']
615 elif 'symbol' in break_results:
616 out_symbol_name = break_results['symbol']
617
618 if symbol_match_exact:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000619 test.assertTrue(
620 symbol_name == out_symbol_name,
621 "Symbol name '%s' doesn't match resultant symbol '%s'." %
622 (symbol_name,
623 out_symbol_name))
Jim Ingham63dfc722012-09-22 00:05:11 +0000624 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000625 test.assertTrue(
626 out_symbol_name.find(symbol_name) != -
627 1,
628 "Symbol name '%s' isn't in resultant symbol '%s'." %
629 (symbol_name,
630 out_symbol_name))
Jim Ingham63dfc722012-09-22 00:05:11 +0000631
632 if module_name:
Ilia K055ad9b2015-05-18 13:41:01 +0000633 out_module_name = None
Jim Ingham63dfc722012-09-22 00:05:11 +0000634 if 'module' in break_results:
635 out_module_name = break_results['module']
Kate Stoneb9c1b512016-09-06 20:57:50 +0000636
637 test.assertTrue(
638 module_name.find(out_module_name) != -
639 1,
640 "Symbol module name '%s' isn't in expected module name '%s'." %
641 (out_module_name,
642 module_name))
Jim Ingham63dfc722012-09-22 00:05:11 +0000643
644# ==================================================
Johnny Chenf4f70bb2010-10-22 21:31:03 +0000645# Utility functions related to Threads and Processes
646# ==================================================
Johnny Chen28ae2942010-10-07 22:15:58 +0000647
Kate Stoneb9c1b512016-09-06 20:57:50 +0000648
Johnny Chend3699082011-04-25 22:04:05 +0000649def get_stopped_threads(process, reason):
Johnny Chen75ec1592011-05-26 21:53:05 +0000650 """Returns the thread(s) with the specified stop reason in a list.
651
652 The list can be empty if no such thread exists.
653 """
Johnny Chend3699082011-04-25 22:04:05 +0000654 threads = []
Johnny Chene69c7482011-04-28 22:57:01 +0000655 for t in process:
Johnny Chend3699082011-04-25 22:04:05 +0000656 if t.GetStopReason() == reason:
657 threads.append(t)
658 return threads
659
Kate Stoneb9c1b512016-09-06 20:57:50 +0000660
Johnny Chend3699082011-04-25 22:04:05 +0000661def get_stopped_thread(process, reason):
662 """A convenience function which returns the first thread with the given stop
663 reason or None.
664
665 Example usages:
666
667 1. Get the stopped thread due to a breakpoint condition
668
669 ...
670 from lldbutil import get_stopped_thread
Johnny Chen5a0bee72011-06-15 22:14:12 +0000671 thread = get_stopped_thread(process, lldb.eStopReasonPlanComplete)
Greg Clayton53c5ddf2013-03-19 17:59:30 +0000672 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition")
Johnny Chend3699082011-04-25 22:04:05 +0000673 ...
674
675 2. Get the thread stopped due to a breakpoint
676
677 ...
678 from lldbutil import get_stopped_thread
Johnny Chen5a0bee72011-06-15 22:14:12 +0000679 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
Greg Clayton53c5ddf2013-03-19 17:59:30 +0000680 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint")
Johnny Chend3699082011-04-25 22:04:05 +0000681 ...
682
683 """
684 threads = get_stopped_threads(process, reason)
685 if len(threads) == 0:
686 return None
687 return threads[0]
688
Kate Stoneb9c1b512016-09-06 20:57:50 +0000689
Zachary Turner1da094a2016-01-22 23:54:41 +0000690def get_threads_stopped_at_breakpoint_id(process, bpid):
Johnny Chend0fef812011-04-25 23:38:13 +0000691 """ For a stopped process returns the thread stopped at the breakpoint passed in bkpt"""
692 stopped_threads = []
693 threads = []
694
Kate Stoneb9c1b512016-09-06 20:57:50 +0000695 stopped_threads = get_stopped_threads(process, lldb.eStopReasonBreakpoint)
Johnny Chend0fef812011-04-25 23:38:13 +0000696
697 if len(stopped_threads) == 0:
698 return threads
Kate Stoneb9c1b512016-09-06 20:57:50 +0000699
Johnny Chend0fef812011-04-25 23:38:13 +0000700 for thread in stopped_threads:
Johnny Chen32391242011-12-22 20:21:46 +0000701 # Make sure we've hit our breakpoint...
Kate Stoneb9c1b512016-09-06 20:57:50 +0000702 break_id = thread.GetStopReasonDataAtIndex(0)
Zachary Turner1da094a2016-01-22 23:54:41 +0000703 if break_id == bpid:
Johnny Chend0fef812011-04-25 23:38:13 +0000704 threads.append(thread)
705
706 return threads
707
Kate Stoneb9c1b512016-09-06 20:57:50 +0000708
709def get_threads_stopped_at_breakpoint(process, bkpt):
Zachary Turner1da094a2016-01-22 23:54:41 +0000710 return get_threads_stopped_at_breakpoint_id(process, bkpt.GetID())
711
Kate Stoneb9c1b512016-09-06 20:57:50 +0000712
713def get_one_thread_stopped_at_breakpoint_id(
714 process, bpid, require_exactly_one=True):
Zachary Turner1da094a2016-01-22 23:54:41 +0000715 threads = get_threads_stopped_at_breakpoint_id(process, bpid)
Zachary Turner783550b2016-01-21 21:07:30 +0000716 if len(threads) == 0:
717 return None
718 if require_exactly_one and len(threads) != 1:
719 return None
720
721 return threads[0]
722
Zachary Turner1da094a2016-01-22 23:54:41 +0000723
Kate Stoneb9c1b512016-09-06 20:57:50 +0000724def get_one_thread_stopped_at_breakpoint(
725 process, bkpt, require_exactly_one=True):
726 return get_one_thread_stopped_at_breakpoint_id(
727 process, bkpt.GetID(), require_exactly_one)
728
729
730def is_thread_crashed(test, thread):
Pavel Labathc4e25c92015-05-29 10:13:03 +0000731 """In the test suite we dereference a null pointer to simulate a crash. The way this is
732 reported depends on the platform."""
733 if test.platformIsDarwin():
Kate Stoneb9c1b512016-09-06 20:57:50 +0000734 return thread.GetStopReason(
735 ) == lldb.eStopReasonException and "EXC_BAD_ACCESS" in thread.GetStopDescription(100)
Pavel Labathc4e25c92015-05-29 10:13:03 +0000736 elif test.getPlatform() == "linux":
Kate Stoneb9c1b512016-09-06 20:57:50 +0000737 return thread.GetStopReason() == lldb.eStopReasonSignal and thread.GetStopReasonDataAtIndex(
738 0) == thread.GetProcess().GetUnixSignals().GetSignalNumberFromName("SIGSEGV")
Pavel Labathc4e25c92015-05-29 10:13:03 +0000739 else:
740 return "invalid address" in thread.GetStopDescription(100)
741
Kate Stoneb9c1b512016-09-06 20:57:50 +0000742
743def get_crashed_threads(test, process):
Pavel Labathc4e25c92015-05-29 10:13:03 +0000744 threads = []
745 if process.GetState() != lldb.eStateStopped:
746 return threads
747 for thread in process:
748 if is_thread_crashed(test, thread):
749 threads.append(thread)
750 return threads
751
Jim Ingham0423fca2018-02-01 21:35:50 +0000752# Helper functions for run_to_{source,name}_breakpoint:
753
Jim Ingham3815e702018-09-13 21:35:32 +0000754def run_to_breakpoint_make_target(test, exe_name = "a.out", in_cwd = True):
Jim Ingham0423fca2018-02-01 21:35:50 +0000755 if in_cwd:
756 exe = test.getBuildArtifact(exe_name)
Raphael Isemann23d7a9e2018-07-27 22:20:59 +0000757
Jim Ingham0423fca2018-02-01 21:35:50 +0000758 # Create the target
759 target = test.dbg.CreateTarget(exe)
760 test.assertTrue(target, "Target: %s is not valid."%(exe_name))
761 return target
762
Jim Ingham3815e702018-09-13 21:35:32 +0000763def run_to_breakpoint_do_run(test, target, bkpt, launch_info = None):
Jim Ingham0423fca2018-02-01 21:35:50 +0000764
765 # Launch the process, and do not stop at the entry point.
766 if not launch_info:
767 launch_info = lldb.SBLaunchInfo(None)
768 launch_info.SetWorkingDirectory(test.get_process_working_directory())
769
770 error = lldb.SBError()
771 process = target.Launch(launch_info, error)
772
Raphael Isemann23d7a9e2018-07-27 22:20:59 +0000773 test.assertTrue(process,
774 "Could not create a valid process for %s: %s"%(target.GetExecutable().GetFilename(),
Jim Ingham0423fca2018-02-01 21:35:50 +0000775 error.GetCString()))
776
777 # Frame #0 should be at our breakpoint.
778 threads = get_threads_stopped_at_breakpoint(
779 process, bkpt)
780
781 test.assertTrue(len(threads) == 1, "Expected 1 thread to stop at breakpoint, %d did."%(len(threads)))
782 thread = threads[0]
783 return (target, process, thread, bkpt)
784
Raphael Isemann23d7a9e2018-07-27 22:20:59 +0000785def run_to_name_breakpoint (test, bkpt_name, launch_info = None,
Jim Ingham0423fca2018-02-01 21:35:50 +0000786 exe_name = "a.out",
Jim Ingham40207d52018-02-02 18:39:25 +0000787 bkpt_module = None,
Jim Ingham0423fca2018-02-01 21:35:50 +0000788 in_cwd = True):
Adrian Prantl595048f2018-01-19 23:24:35 +0000789 """Start up a target, using exe_name as the executable, and run it to
Jim Ingham40207d52018-02-02 18:39:25 +0000790 a breakpoint set by name on bkpt_name restricted to bkpt_module.
Adrian Prantl595048f2018-01-19 23:24:35 +0000791
792 If you want to pass in launch arguments or environment
793 variables, you can optionally pass in an SBLaunchInfo. If you
794 do that, remember to set the working directory as well.
795
796 If your executable isn't called a.out, you can pass that in.
797 And if your executable isn't in the CWD, pass in the absolute
798 path to the executable in exe_name, and set in_cwd to False.
799
Jim Ingham40207d52018-02-02 18:39:25 +0000800 If you need to restrict the breakpoint to a particular module,
801 pass the module name (a string not a FileSpec) in bkpt_module. If
802 nothing is passed in setting will be unrestricted.
803
Jim Inghama15e7f22017-07-06 02:18:16 +0000804 If the target isn't valid, the breakpoint isn't found, or hit, the
805 function will cause a testsuite failure.
Adrian Prantl595048f2018-01-19 23:24:35 +0000806
807 If successful it returns a tuple with the target process and
Jim Ingham40207d52018-02-02 18:39:25 +0000808 thread that hit the breakpoint, and the breakpoint that we set
809 for you.
Adrian Prantl595048f2018-01-19 23:24:35 +0000810 """
Jim Inghama15e7f22017-07-06 02:18:16 +0000811
Jim Ingham0423fca2018-02-01 21:35:50 +0000812 target = run_to_breakpoint_make_target(test, exe_name, in_cwd)
Jim Inghama15e7f22017-07-06 02:18:16 +0000813
Jim Ingham40207d52018-02-02 18:39:25 +0000814 breakpoint = target.BreakpointCreateByName(bkpt_name, bkpt_module)
815
816
Jim Ingham0423fca2018-02-01 21:35:50 +0000817 test.assertTrue(breakpoint.GetNumLocations() > 0,
818 "No locations found for name breakpoint: '%s'."%(bkpt_name))
819 return run_to_breakpoint_do_run(test, target, breakpoint, launch_info)
820
821def run_to_source_breakpoint(test, bkpt_pattern, source_spec,
822 launch_info = None, exe_name = "a.out",
Jim Ingham40207d52018-02-02 18:39:25 +0000823 bkpt_module = None,
Jim Ingham0423fca2018-02-01 21:35:50 +0000824 in_cwd = True):
825 """Start up a target, using exe_name as the executable, and run it to
826 a breakpoint set by source regex bkpt_pattern.
827
828 The rest of the behavior is the same as run_to_name_breakpoint.
829 """
830
831 target = run_to_breakpoint_make_target(test, exe_name, in_cwd)
Jim Inghama15e7f22017-07-06 02:18:16 +0000832 # Set the breakpoints
833 breakpoint = target.BreakpointCreateBySourceRegex(
Jim Ingham40207d52018-02-02 18:39:25 +0000834 bkpt_pattern, source_spec, bkpt_module)
Raphael Isemann23d7a9e2018-07-27 22:20:59 +0000835 test.assertTrue(breakpoint.GetNumLocations() > 0,
Adrian Prantl431b1582018-08-30 15:11:00 +0000836 'No locations found for source breakpoint: "%s", file: "%s", dir: "%s"'
837 %(bkpt_pattern, source_spec.GetFilename(), source_spec.GetDirectory()))
Jim Ingham0423fca2018-02-01 21:35:50 +0000838 return run_to_breakpoint_do_run(test, target, breakpoint, launch_info)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000839
Adrian Prantl431b1582018-08-30 15:11:00 +0000840def run_to_line_breakpoint(test, source_spec, line_number, column = 0,
841 launch_info = None, exe_name = "a.out",
842 bkpt_module = None,
843 in_cwd = True):
844 """Start up a target, using exe_name as the executable, and run it to
845 a breakpoint set by (source_spec, line_number(, column)).
846
847 The rest of the behavior is the same as run_to_name_breakpoint.
848 """
849
850 target = run_to_breakpoint_make_target(test, exe_name, in_cwd)
851 # Set the breakpoints
852 breakpoint = target.BreakpointCreateByLocation(
853 source_spec, line_number, column, 0, lldb.SBFileSpecList())
854 test.assertTrue(breakpoint.GetNumLocations() > 0,
855 'No locations found for line breakpoint: "%s:%d(:%d)", dir: "%s"'
856 %(source_spec.GetFilename(), line_number, column,
857 source_spec.GetDirectory()))
858 return run_to_breakpoint_do_run(test, target, breakpoint, launch_info)
859
860
Kate Stoneb9c1b512016-09-06 20:57:50 +0000861def continue_to_breakpoint(process, bkpt):
Johnny Chend0fef812011-04-25 23:38:13 +0000862 """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None"""
863 process.Continue()
864 if process.GetState() != lldb.eStateStopped:
865 return None
866 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000867 return get_threads_stopped_at_breakpoint(process, bkpt)
868
Johnny Chend0fef812011-04-25 23:38:13 +0000869
Johnny Chena4603162011-03-09 23:45:56 +0000870def get_caller_symbol(thread):
871 """
872 Returns the symbol name for the call site of the leaf function.
873 """
874 depth = thread.GetNumFrames()
875 if depth <= 1:
876 return None
877 caller = thread.GetFrameAtIndex(1).GetSymbol()
878 if caller:
879 return caller.GetName()
880 else:
881 return None
882
883
Johnny Chend0fef812011-04-25 23:38:13 +0000884def get_function_names(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000885 """
886 Returns a sequence of function names from the stack frames of this thread.
887 """
888 def GetFuncName(i):
Johnny Chen4cfd07e2011-06-20 00:26:39 +0000889 return thread.GetFrameAtIndex(i).GetFunctionName()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000890
Zachary Turner744cd5d2015-10-26 16:49:57 +0000891 return list(map(GetFuncName, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000892
893
Johnny Chend0fef812011-04-25 23:38:13 +0000894def get_symbol_names(thread):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000895 """
896 Returns a sequence of symbols for this thread.
897 """
898 def GetSymbol(i):
899 return thread.GetFrameAtIndex(i).GetSymbol().GetName()
900
Zachary Turner744cd5d2015-10-26 16:49:57 +0000901 return list(map(GetSymbol, list(range(thread.GetNumFrames()))))
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000902
903
Johnny Chend0fef812011-04-25 23:38:13 +0000904def get_pc_addresses(thread):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000905 """
906 Returns a sequence of pc addresses for this thread.
907 """
908 def GetPCAddress(i):
909 return thread.GetFrameAtIndex(i).GetPCAddress()
910
Zachary Turner744cd5d2015-10-26 16:49:57 +0000911 return list(map(GetPCAddress, list(range(thread.GetNumFrames()))))
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000912
913
Johnny Chend0fef812011-04-25 23:38:13 +0000914def get_filenames(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000915 """
916 Returns a sequence of file names from the stack frames of this thread.
917 """
918 def GetFilename(i):
Kate Stoneb9c1b512016-09-06 20:57:50 +0000919 return thread.GetFrameAtIndex(
920 i).GetLineEntry().GetFileSpec().GetFilename()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000921
Zachary Turner744cd5d2015-10-26 16:49:57 +0000922 return list(map(GetFilename, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000923
924
Johnny Chend0fef812011-04-25 23:38:13 +0000925def get_line_numbers(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000926 """
927 Returns a sequence of line numbers from the stack frames of this thread.
928 """
929 def GetLineNumber(i):
930 return thread.GetFrameAtIndex(i).GetLineEntry().GetLine()
931
Zachary Turner744cd5d2015-10-26 16:49:57 +0000932 return list(map(GetLineNumber, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000933
934
Johnny Chend0fef812011-04-25 23:38:13 +0000935def get_module_names(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000936 """
937 Returns a sequence of module names from the stack frames of this thread.
938 """
939 def GetModuleName(i):
Kate Stoneb9c1b512016-09-06 20:57:50 +0000940 return thread.GetFrameAtIndex(
941 i).GetModule().GetFileSpec().GetFilename()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000942
Zachary Turner744cd5d2015-10-26 16:49:57 +0000943 return list(map(GetModuleName, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000944
945
Johnny Chend0fef812011-04-25 23:38:13 +0000946def get_stack_frames(thread):
Johnny Chen43a651c2010-09-09 00:55:07 +0000947 """
948 Returns a sequence of stack frames for this thread.
949 """
950 def GetStackFrame(i):
951 return thread.GetFrameAtIndex(i)
952
Zachary Turner744cd5d2015-10-26 16:49:57 +0000953 return list(map(GetStackFrame, list(range(thread.GetNumFrames()))))
Johnny Chen43a651c2010-09-09 00:55:07 +0000954
955
Kate Stoneb9c1b512016-09-06 20:57:50 +0000956def print_stacktrace(thread, string_buffer=False):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000957 """Prints a simple stack trace of this thread."""
Johnny Chen6c704992010-10-07 18:52:48 +0000958
Zachary Turner814236d2015-10-21 17:48:52 +0000959 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000960 target = thread.GetProcess().GetTarget()
961
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000962 depth = thread.GetNumFrames()
963
Johnny Chend0fef812011-04-25 23:38:13 +0000964 mods = get_module_names(thread)
965 funcs = get_function_names(thread)
966 symbols = get_symbol_names(thread)
967 files = get_filenames(thread)
968 lines = get_line_numbers(thread)
969 addrs = get_pc_addresses(thread)
Johnny Chen6c704992010-10-07 18:52:48 +0000970
Johnny Chen567a0452010-10-25 19:13:52 +0000971 if thread.GetStopReason() != lldb.eStopReasonInvalid:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000972 desc = "stop reason=" + stop_reason_to_str(thread.GetStopReason())
Johnny Chen567a0452010-10-25 19:13:52 +0000973 else:
974 desc = ""
Kate Stoneb9c1b512016-09-06 20:57:50 +0000975 print(
976 "Stack trace for thread id={0:#x} name={1} queue={2} ".format(
977 thread.GetThreadID(),
978 thread.GetName(),
979 thread.GetQueueName()) + desc,
980 file=output)
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000981
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000982 for i in range(depth):
983 frame = thread.GetFrameAtIndex(i)
984 function = frame.GetFunction()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000985
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000986 load_addr = addrs[i].GetLoadAddress(target)
Johnny Chen3cd1e552011-05-25 19:06:18 +0000987 if not function:
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000988 file_addr = addrs[i].GetFileAddress()
Johnny Chen0d4f6dd2011-06-16 22:07:48 +0000989 start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress()
990 symbol_offset = file_addr - start_addr
Kate Stoneb9c1b512016-09-06 20:57:50 +0000991 print(
992 " frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format(
993 num=i,
994 addr=load_addr,
995 mod=mods[i],
996 symbol=symbols[i],
997 offset=symbol_offset),
998 file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000999 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001000 print(
1001 " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format(
1002 num=i,
1003 addr=load_addr,
1004 mod=mods[i],
1005 func='%s [inlined]' %
1006 funcs[i] if frame.IsInlined() else funcs[i],
1007 file=files[i],
1008 line=lines[i],
1009 args=get_args_as_string(
1010 frame,
1011 showFuncName=False) if not frame.IsInlined() else '()'),
1012 file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +00001013
1014 if string_buffer:
Johnny Chend5d6fac2010-10-15 23:33:18 +00001015 return output.getvalue()
Johnny Chen7ea9aee2010-10-07 21:38:28 +00001016
1017
Kate Stoneb9c1b512016-09-06 20:57:50 +00001018def print_stacktraces(process, string_buffer=False):
Johnny Chen7ea9aee2010-10-07 21:38:28 +00001019 """Prints the stack traces of all the threads."""
1020
Zachary Turner814236d2015-10-21 17:48:52 +00001021 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chen7ea9aee2010-10-07 21:38:28 +00001022
Zachary Turnerff890da2015-10-19 23:45:41 +00001023 print("Stack traces for " + str(process), file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +00001024
Johnny Chenae9639a2011-05-05 18:50:56 +00001025 for thread in process:
Zachary Turnerff890da2015-10-19 23:45:41 +00001026 print(print_stacktrace(thread, string_buffer=True), file=output)
Johnny Chen6c704992010-10-07 18:52:48 +00001027
1028 if string_buffer:
Johnny Chend5d6fac2010-10-15 23:33:18 +00001029 return output.getvalue()
Johnny Chenb21c52e2011-05-08 17:25:27 +00001030
Kate Stoneb9c1b512016-09-06 20:57:50 +00001031
1032def expect_state_changes(test, listener, process, states, timeout=5):
Pavel Labath5dcb0252015-09-02 09:12:28 +00001033 """Listens for state changed events on the listener and makes sure they match what we
1034 expect. Stop-and-restart events (where GetRestartedFromEvent() returns true) are ignored."""
Pavel Labathe5c98082016-01-06 11:40:06 +00001035
Pavel Labath5dcb0252015-09-02 09:12:28 +00001036 for expected_state in states:
Pavel Labathe5c98082016-01-06 11:40:06 +00001037 def get_next_event():
1038 event = lldb.SBEvent()
Kate Stoneb9c1b512016-09-06 20:57:50 +00001039 if not listener.WaitForEventForBroadcasterWithType(
1040 timeout,
1041 process.GetBroadcaster(),
1042 lldb.SBProcess.eBroadcastBitStateChanged,
1043 event):
1044 test.fail(
1045 "Timed out while waiting for a transition to state %s" %
Pavel Labathe5c98082016-01-06 11:40:06 +00001046 lldb.SBDebugger.StateAsCString(expected_state))
1047 return event
Pavel Labath5dcb0252015-09-02 09:12:28 +00001048
Pavel Labathe5c98082016-01-06 11:40:06 +00001049 event = get_next_event()
1050 while (lldb.SBProcess.GetStateFromEvent(event) == lldb.eStateStopped and
1051 lldb.SBProcess.GetRestartedFromEvent(event)):
1052 # Ignore restarted event and the subsequent running event.
1053 event = get_next_event()
Kate Stoneb9c1b512016-09-06 20:57:50 +00001054 test.assertEqual(
1055 lldb.SBProcess.GetStateFromEvent(event),
1056 lldb.eStateRunning,
1057 "Restarted event followed by a running event")
Pavel Labathe5c98082016-01-06 11:40:06 +00001058 event = get_next_event()
Pavel Labath5dcb0252015-09-02 09:12:28 +00001059
Kate Stoneb9c1b512016-09-06 20:57:50 +00001060 test.assertEqual(
1061 lldb.SBProcess.GetStateFromEvent(event),
1062 expected_state)
Pavel Labath5dcb0252015-09-02 09:12:28 +00001063
Johnny Chenb21c52e2011-05-08 17:25:27 +00001064# ===================================
1065# Utility functions related to Frames
1066# ===================================
1067
Kate Stoneb9c1b512016-09-06 20:57:50 +00001068
Johnny Chenad7372c2011-05-12 00:32:41 +00001069def get_parent_frame(frame):
1070 """
1071 Returns the parent frame of the input frame object; None if not available.
1072 """
1073 thread = frame.GetThread()
1074 parent_found = False
1075 for f in thread:
1076 if parent_found:
1077 return f
1078 if f.GetFrameID() == frame.GetFrameID():
1079 parent_found = True
1080
1081 # If we reach here, no parent has been found, return None.
1082 return None
1083
Kate Stoneb9c1b512016-09-06 20:57:50 +00001084
Johnny Chen0d4f6dd2011-06-16 22:07:48 +00001085def get_args_as_string(frame, showFuncName=True):
Johnny Chenad7372c2011-05-12 00:32:41 +00001086 """
1087 Returns the args of the input frame object as a string.
1088 """
1089 # arguments => True
1090 # locals => False
1091 # statics => False
1092 # in_scope_only => True
Kate Stoneb9c1b512016-09-06 20:57:50 +00001093 vars = frame.GetVariables(True, False, False, True) # type of SBValueList
1094 args = [] # list of strings
Johnny Chenad7372c2011-05-12 00:32:41 +00001095 for var in vars:
1096 args.append("(%s)%s=%s" % (var.GetTypeName(),
1097 var.GetName(),
Greg Claytonfe42ac42011-08-03 22:57:10 +00001098 var.GetValue()))
Johnny Chen3cd1e552011-05-25 19:06:18 +00001099 if frame.GetFunction():
Johnny Chen52b0ffd92011-05-13 00:44:49 +00001100 name = frame.GetFunction().GetName()
Johnny Chen3cd1e552011-05-25 19:06:18 +00001101 elif frame.GetSymbol():
Johnny Chen52b0ffd92011-05-13 00:44:49 +00001102 name = frame.GetSymbol().GetName()
1103 else:
1104 name = ""
Johnny Chen0d4f6dd2011-06-16 22:07:48 +00001105 if showFuncName:
1106 return "%s(%s)" % (name, ", ".join(args))
1107 else:
1108 return "(%s)" % (", ".join(args))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001109
1110
1111def print_registers(frame, string_buffer=False):
Johnny Chen2158b972011-05-08 18:55:37 +00001112 """Prints all the register sets of the frame."""
Johnny Chenb21c52e2011-05-08 17:25:27 +00001113
Zachary Turner814236d2015-10-21 17:48:52 +00001114 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chenb21c52e2011-05-08 17:25:27 +00001115
Zachary Turnerff890da2015-10-19 23:45:41 +00001116 print("Register sets for " + str(frame), file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +00001117
Kate Stoneb9c1b512016-09-06 20:57:50 +00001118 registerSet = frame.GetRegisters() # Return type of SBValueList.
1119 print("Frame registers (size of register set = %d):" %
1120 registerSet.GetSize(), file=output)
Johnny Chen64ff7e62011-05-10 19:21:13 +00001121 for value in registerSet:
Zachary Turner35d017f2015-10-23 17:04:29 +00001122 #print(value, file=output)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001123 print("%s (number of children = %d):" %
1124 (value.GetName(), value.GetNumChildren()), file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +00001125 for child in value:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001126 print(
1127 "Name: %s, Value: %s" %
1128 (child.GetName(),
1129 child.GetValue()),
1130 file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +00001131
1132 if string_buffer:
1133 return output.getvalue()
Johnny Chen64ff7e62011-05-10 19:21:13 +00001134
Kate Stoneb9c1b512016-09-06 20:57:50 +00001135
Johnny Chen64ff7e62011-05-10 19:21:13 +00001136def get_registers(frame, kind):
1137 """Returns the registers given the frame and the kind of registers desired.
1138
1139 Returns None if there's no such kind.
1140 """
Kate Stoneb9c1b512016-09-06 20:57:50 +00001141 registerSet = frame.GetRegisters() # Return type of SBValueList.
Johnny Chen64ff7e62011-05-10 19:21:13 +00001142 for value in registerSet:
1143 if kind.lower() in value.GetName().lower():
1144 return value
1145
1146 return None
1147
Kate Stoneb9c1b512016-09-06 20:57:50 +00001148
Johnny Chen64ff7e62011-05-10 19:21:13 +00001149def get_GPRs(frame):
1150 """Returns the general purpose registers of the frame as an SBValue.
1151
Johnny Chene9e86892011-05-10 23:01:44 +00001152 The returned SBValue object is iterable. An example:
1153 ...
1154 from lldbutil import get_GPRs
1155 regs = get_GPRs(frame)
1156 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +00001157 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +00001158 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +00001159 """
1160 return get_registers(frame, "general purpose")
1161
Kate Stoneb9c1b512016-09-06 20:57:50 +00001162
Johnny Chen64ff7e62011-05-10 19:21:13 +00001163def get_FPRs(frame):
1164 """Returns the floating point registers of the frame as an SBValue.
1165
Johnny Chene9e86892011-05-10 23:01:44 +00001166 The returned SBValue object is iterable. An example:
1167 ...
1168 from lldbutil import get_FPRs
1169 regs = get_FPRs(frame)
1170 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +00001171 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +00001172 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +00001173 """
1174 return get_registers(frame, "floating point")
1175
Kate Stoneb9c1b512016-09-06 20:57:50 +00001176
Johnny Chen64ff7e62011-05-10 19:21:13 +00001177def get_ESRs(frame):
1178 """Returns the exception state registers of the frame as an SBValue.
1179
Johnny Chene9e86892011-05-10 23:01:44 +00001180 The returned SBValue object is iterable. An example:
1181 ...
1182 from lldbutil import get_ESRs
1183 regs = get_ESRs(frame)
1184 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +00001185 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +00001186 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +00001187 """
1188 return get_registers(frame, "exception state")
Johnny Chen989b7ef2011-07-22 00:47:58 +00001189
Johnny Chenefee1cd2011-07-22 00:51:54 +00001190# ======================================
1191# Utility classes/functions for SBValues
1192# ======================================
Johnny Chen989b7ef2011-07-22 00:47:58 +00001193
Kate Stoneb9c1b512016-09-06 20:57:50 +00001194
Johnny Chen989b7ef2011-07-22 00:47:58 +00001195class BasicFormatter(object):
Johnny Chen36d7d912011-07-22 22:01:35 +00001196 """The basic formatter inspects the value object and prints the value."""
Kate Stoneb9c1b512016-09-06 20:57:50 +00001197
Johnny Chen989b7ef2011-07-22 00:47:58 +00001198 def format(self, value, buffer=None, indent=0):
1199 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +00001200 output = SixStringIO()
Johnny Chen989b7ef2011-07-22 00:47:58 +00001201 else:
1202 output = buffer
Johnny Chen36d7d912011-07-22 22:01:35 +00001203 # If there is a summary, it suffices.
1204 val = value.GetSummary()
1205 # Otherwise, get the value.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001206 if val is None:
Johnny Chen36d7d912011-07-22 22:01:35 +00001207 val = value.GetValue()
Kate Stoneb9c1b512016-09-06 20:57:50 +00001208 if val is None and value.GetNumChildren() > 0:
Johnny Chen36d7d912011-07-22 22:01:35 +00001209 val = "%s (location)" % value.GetLocation()
Zachary Turnerff890da2015-10-19 23:45:41 +00001210 print("{indentation}({type}) {name} = {value}".format(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001211 indentation=' ' * indent,
1212 type=value.GetTypeName(),
1213 name=value.GetName(),
1214 value=val), file=output)
Johnny Chen989b7ef2011-07-22 00:47:58 +00001215 return output.getvalue()
1216
Kate Stoneb9c1b512016-09-06 20:57:50 +00001217
Johnny Chen989b7ef2011-07-22 00:47:58 +00001218class ChildVisitingFormatter(BasicFormatter):
Johnny Chen36d7d912011-07-22 22:01:35 +00001219 """The child visiting formatter prints the value and its immediate children.
1220
1221 The constructor takes a keyword arg: indent_child, which defaults to 2.
1222 """
Kate Stoneb9c1b512016-09-06 20:57:50 +00001223
Johnny Chen36d7d912011-07-22 22:01:35 +00001224 def __init__(self, indent_child=2):
1225 """Default indentation of 2 SPC's for the children."""
1226 self.cindent = indent_child
Kate Stoneb9c1b512016-09-06 20:57:50 +00001227
Johnny Chen989b7ef2011-07-22 00:47:58 +00001228 def format(self, value, buffer=None):
1229 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +00001230 output = SixStringIO()
Johnny Chen989b7ef2011-07-22 00:47:58 +00001231 else:
1232 output = buffer
1233
1234 BasicFormatter.format(self, value, buffer=output)
1235 for child in value:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001236 BasicFormatter.format(
1237 self, child, buffer=output, indent=self.cindent)
Johnny Chen36d7d912011-07-22 22:01:35 +00001238
1239 return output.getvalue()
1240
Kate Stoneb9c1b512016-09-06 20:57:50 +00001241
Johnny Chen36d7d912011-07-22 22:01:35 +00001242class RecursiveDecentFormatter(BasicFormatter):
1243 """The recursive decent formatter prints the value and the decendents.
1244
1245 The constructor takes two keyword args: indent_level, which defaults to 0,
1246 and indent_child, which defaults to 2. The current indentation level is
1247 determined by indent_level, while the immediate children has an additional
Kate Stoneb9c1b512016-09-06 20:57:50 +00001248 indentation by inden_child.
Johnny Chen36d7d912011-07-22 22:01:35 +00001249 """
Kate Stoneb9c1b512016-09-06 20:57:50 +00001250
Johnny Chen36d7d912011-07-22 22:01:35 +00001251 def __init__(self, indent_level=0, indent_child=2):
1252 self.lindent = indent_level
1253 self.cindent = indent_child
Kate Stoneb9c1b512016-09-06 20:57:50 +00001254
Johnny Chen36d7d912011-07-22 22:01:35 +00001255 def format(self, value, buffer=None):
1256 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +00001257 output = SixStringIO()
Johnny Chen36d7d912011-07-22 22:01:35 +00001258 else:
1259 output = buffer
1260
1261 BasicFormatter.format(self, value, buffer=output, indent=self.lindent)
1262 new_indent = self.lindent + self.cindent
1263 for child in value:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001264 if child.GetSummary() is not None:
1265 BasicFormatter.format(
1266 self, child, buffer=output, indent=new_indent)
Johnny Chen36d7d912011-07-22 22:01:35 +00001267 else:
1268 if child.GetNumChildren() > 0:
1269 rdf = RecursiveDecentFormatter(indent_level=new_indent)
1270 rdf.format(child, buffer=output)
1271 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001272 BasicFormatter.format(
1273 self, child, buffer=output, indent=new_indent)
Johnny Chen989b7ef2011-07-22 00:47:58 +00001274
1275 return output.getvalue()
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001276
1277# ===========================================================
1278# Utility functions for path manipulation on remote platforms
1279# ===========================================================
1280
Kate Stoneb9c1b512016-09-06 20:57:50 +00001281
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001282def join_remote_paths(*paths):
1283 # TODO: update with actual platform name for remote windows once it exists
1284 if lldb.remote_platform.GetName() == 'remote-windows':
1285 return os.path.join(*paths).replace(os.path.sep, '\\')
1286 return os.path.join(*paths).replace(os.path.sep, '/')
1287
Kate Stoneb9c1b512016-09-06 20:57:50 +00001288
Pavel Labathf3a9ab02018-02-21 15:33:53 +00001289def append_to_process_working_directory(test, *paths):
Chaoren Lin5d76b1b2015-06-06 00:25:50 +00001290 remote = lldb.remote_platform
1291 if remote:
1292 return join_remote_paths(remote.GetWorkingDirectory(), *paths)
Pavel Labathf3a9ab02018-02-21 15:33:53 +00001293 return os.path.join(test.getBuildDir(), *paths)
Chaoren Linf59d05092015-06-02 16:46:28 +00001294
1295# ==================================================
1296# Utility functions to get the correct signal number
1297# ==================================================
1298
1299import signal
1300
Kate Stoneb9c1b512016-09-06 20:57:50 +00001301
Chaoren Linf59d05092015-06-02 16:46:28 +00001302def get_signal_number(signal_name):
1303 platform = lldb.remote_platform
Chaoren Lin98d0a4b2015-07-14 01:09:28 +00001304 if platform and platform.IsValid():
1305 signals = platform.GetUnixSignals()
1306 if signals.IsValid():
Chaoren Lin264e5422015-06-02 18:31:57 +00001307 signal_number = signals.GetSignalNumberFromName(signal_name)
1308 if signal_number > 0:
1309 return signal_number
Chaoren Lin98d0a4b2015-07-14 01:09:28 +00001310 # No remote platform; fall back to using local python signals.
Chaoren Linf59d05092015-06-02 16:46:28 +00001311 return getattr(signal, signal_name)
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001312
Kate Stoneb9c1b512016-09-06 20:57:50 +00001313
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001314class PrintableRegex(object):
Kate Stoneb9c1b512016-09-06 20:57:50 +00001315
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001316 def __init__(self, text):
1317 self.regex = re.compile(text)
1318 self.text = text
Kate Stoneb9c1b512016-09-06 20:57:50 +00001319
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001320 def match(self, str):
1321 return self.regex.match(str)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001322
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001323 def __str__(self):
1324 return "%s" % (self.text)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001325
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001326 def __repr__(self):
1327 return "re.compile(%s) -> %s" % (self.text, self.regex)
1328
Kate Stoneb9c1b512016-09-06 20:57:50 +00001329
Enrico Granataef4fa442015-12-04 19:50:05 +00001330def skip_if_callable(test, mycallable, reason):
1331 if six.callable(mycallable):
1332 if mycallable(test):
1333 test.skipTest(reason)
1334 return True
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001335 return False
1336
Kate Stoneb9c1b512016-09-06 20:57:50 +00001337
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001338def skip_if_library_missing(test, target, library):
1339 def find_library(target, library):
1340 for module in target.modules:
1341 filename = module.file.GetFilename()
1342 if isinstance(library, str):
1343 if library == filename:
1344 return False
1345 elif hasattr(library, 'match'):
1346 if library.match(filename):
1347 return False
1348 return True
Kate Stoneb9c1b512016-09-06 20:57:50 +00001349
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001350 def find_library_callable(test):
1351 return find_library(target, library)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001352 return skip_if_callable(
1353 test,
1354 find_library_callable,
1355 "could not find library matching '%s' in target %s" %
1356 (library,
1357 target))
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001358
Kate Stoneb9c1b512016-09-06 20:57:50 +00001359
Pavel Labath107052f2018-03-15 13:47:09 +00001360def read_file_on_target(test, remote):
1361 if lldb.remote_platform:
1362 local = test.getBuildArtifact("file_from_target")
1363 error = lldb.remote_platform.Get(lldb.SBFileSpec(remote, False),
1364 lldb.SBFileSpec(local, True))
1365 test.assertTrue(error.Success(), "Reading file {0} failed: {1}".format(remote, error))
1366 else:
1367 local = remote
1368 with open(local, 'r') as f:
1369 return f.read()
1370
1371def read_file_from_process_wd(test, name):
1372 path = append_to_process_working_directory(test, name)
1373 return read_file_on_target(test, path)
1374
Kate Stoneb9c1b512016-09-06 20:57:50 +00001375def wait_for_file_on_target(testcase, file_path, max_attempts=6):
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001376 for i in range(max_attempts):
1377 err, retcode, msg = testcase.run_platform_command("ls %s" % file_path)
1378 if err.Success() and retcode == 0:
1379 break
1380 if i < max_attempts:
1381 # Exponential backoff!
Todd Fiala464f7df2016-04-08 18:06:11 +00001382 import time
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001383 time.sleep(pow(2, i) * 0.25)
1384 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001385 testcase.fail(
1386 "File %s not found even after %d attempts." %
1387 (file_path, max_attempts))
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001388
Pavel Labath107052f2018-03-15 13:47:09 +00001389 return read_file_on_target(testcase, file_path)