blob: 16950d7b5cdbc510324445f825fc3c2e6ba93ff9 [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")
Aleksandr Urakova5235af2018-12-03 13:31:13 +0000739 elif test.getPlatform() == "windows":
740 return "Exception 0xc0000005" in thread.GetStopDescription(100)
Pavel Labathc4e25c92015-05-29 10:13:03 +0000741 else:
742 return "invalid address" in thread.GetStopDescription(100)
743
Kate Stoneb9c1b512016-09-06 20:57:50 +0000744
745def get_crashed_threads(test, process):
Pavel Labathc4e25c92015-05-29 10:13:03 +0000746 threads = []
747 if process.GetState() != lldb.eStateStopped:
748 return threads
749 for thread in process:
750 if is_thread_crashed(test, thread):
751 threads.append(thread)
752 return threads
753
Jim Ingham0423fca2018-02-01 21:35:50 +0000754# Helper functions for run_to_{source,name}_breakpoint:
755
Jim Ingham3815e702018-09-13 21:35:32 +0000756def run_to_breakpoint_make_target(test, exe_name = "a.out", in_cwd = True):
Jim Ingham0423fca2018-02-01 21:35:50 +0000757 if in_cwd:
758 exe = test.getBuildArtifact(exe_name)
Raphael Isemann23d7a9e2018-07-27 22:20:59 +0000759
Jim Ingham0423fca2018-02-01 21:35:50 +0000760 # Create the target
761 target = test.dbg.CreateTarget(exe)
762 test.assertTrue(target, "Target: %s is not valid."%(exe_name))
763 return target
764
Jim Ingham3815e702018-09-13 21:35:32 +0000765def run_to_breakpoint_do_run(test, target, bkpt, launch_info = None):
Jim Ingham0423fca2018-02-01 21:35:50 +0000766
767 # Launch the process, and do not stop at the entry point.
768 if not launch_info:
769 launch_info = lldb.SBLaunchInfo(None)
770 launch_info.SetWorkingDirectory(test.get_process_working_directory())
771
772 error = lldb.SBError()
773 process = target.Launch(launch_info, error)
774
Raphael Isemann23d7a9e2018-07-27 22:20:59 +0000775 test.assertTrue(process,
776 "Could not create a valid process for %s: %s"%(target.GetExecutable().GetFilename(),
Jim Ingham0423fca2018-02-01 21:35:50 +0000777 error.GetCString()))
778
779 # Frame #0 should be at our breakpoint.
780 threads = get_threads_stopped_at_breakpoint(
781 process, bkpt)
782
783 test.assertTrue(len(threads) == 1, "Expected 1 thread to stop at breakpoint, %d did."%(len(threads)))
784 thread = threads[0]
785 return (target, process, thread, bkpt)
786
Raphael Isemann23d7a9e2018-07-27 22:20:59 +0000787def run_to_name_breakpoint (test, bkpt_name, launch_info = None,
Jim Ingham0423fca2018-02-01 21:35:50 +0000788 exe_name = "a.out",
Jim Ingham40207d52018-02-02 18:39:25 +0000789 bkpt_module = None,
Jim Ingham0423fca2018-02-01 21:35:50 +0000790 in_cwd = True):
Adrian Prantl595048f2018-01-19 23:24:35 +0000791 """Start up a target, using exe_name as the executable, and run it to
Jim Ingham40207d52018-02-02 18:39:25 +0000792 a breakpoint set by name on bkpt_name restricted to bkpt_module.
Adrian Prantl595048f2018-01-19 23:24:35 +0000793
794 If you want to pass in launch arguments or environment
795 variables, you can optionally pass in an SBLaunchInfo. If you
796 do that, remember to set the working directory as well.
797
798 If your executable isn't called a.out, you can pass that in.
799 And if your executable isn't in the CWD, pass in the absolute
800 path to the executable in exe_name, and set in_cwd to False.
801
Jim Ingham40207d52018-02-02 18:39:25 +0000802 If you need to restrict the breakpoint to a particular module,
803 pass the module name (a string not a FileSpec) in bkpt_module. If
804 nothing is passed in setting will be unrestricted.
805
Jim Inghama15e7f22017-07-06 02:18:16 +0000806 If the target isn't valid, the breakpoint isn't found, or hit, the
807 function will cause a testsuite failure.
Adrian Prantl595048f2018-01-19 23:24:35 +0000808
809 If successful it returns a tuple with the target process and
Jim Ingham40207d52018-02-02 18:39:25 +0000810 thread that hit the breakpoint, and the breakpoint that we set
811 for you.
Adrian Prantl595048f2018-01-19 23:24:35 +0000812 """
Jim Inghama15e7f22017-07-06 02:18:16 +0000813
Jim Ingham0423fca2018-02-01 21:35:50 +0000814 target = run_to_breakpoint_make_target(test, exe_name, in_cwd)
Jim Inghama15e7f22017-07-06 02:18:16 +0000815
Jim Ingham40207d52018-02-02 18:39:25 +0000816 breakpoint = target.BreakpointCreateByName(bkpt_name, bkpt_module)
817
818
Jim Ingham0423fca2018-02-01 21:35:50 +0000819 test.assertTrue(breakpoint.GetNumLocations() > 0,
820 "No locations found for name breakpoint: '%s'."%(bkpt_name))
821 return run_to_breakpoint_do_run(test, target, breakpoint, launch_info)
822
823def run_to_source_breakpoint(test, bkpt_pattern, source_spec,
824 launch_info = None, exe_name = "a.out",
Jim Ingham40207d52018-02-02 18:39:25 +0000825 bkpt_module = None,
Jim Ingham0423fca2018-02-01 21:35:50 +0000826 in_cwd = True):
827 """Start up a target, using exe_name as the executable, and run it to
828 a breakpoint set by source regex bkpt_pattern.
829
830 The rest of the behavior is the same as run_to_name_breakpoint.
831 """
832
833 target = run_to_breakpoint_make_target(test, exe_name, in_cwd)
Jim Inghama15e7f22017-07-06 02:18:16 +0000834 # Set the breakpoints
835 breakpoint = target.BreakpointCreateBySourceRegex(
Jim Ingham40207d52018-02-02 18:39:25 +0000836 bkpt_pattern, source_spec, bkpt_module)
Raphael Isemann23d7a9e2018-07-27 22:20:59 +0000837 test.assertTrue(breakpoint.GetNumLocations() > 0,
Adrian Prantl431b1582018-08-30 15:11:00 +0000838 'No locations found for source breakpoint: "%s", file: "%s", dir: "%s"'
839 %(bkpt_pattern, source_spec.GetFilename(), source_spec.GetDirectory()))
Jim Ingham0423fca2018-02-01 21:35:50 +0000840 return run_to_breakpoint_do_run(test, target, breakpoint, launch_info)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000841
Adrian Prantl431b1582018-08-30 15:11:00 +0000842def run_to_line_breakpoint(test, source_spec, line_number, column = 0,
843 launch_info = None, exe_name = "a.out",
844 bkpt_module = None,
845 in_cwd = True):
846 """Start up a target, using exe_name as the executable, and run it to
847 a breakpoint set by (source_spec, line_number(, column)).
848
849 The rest of the behavior is the same as run_to_name_breakpoint.
850 """
851
852 target = run_to_breakpoint_make_target(test, exe_name, in_cwd)
853 # Set the breakpoints
854 breakpoint = target.BreakpointCreateByLocation(
855 source_spec, line_number, column, 0, lldb.SBFileSpecList())
856 test.assertTrue(breakpoint.GetNumLocations() > 0,
857 'No locations found for line breakpoint: "%s:%d(:%d)", dir: "%s"'
858 %(source_spec.GetFilename(), line_number, column,
859 source_spec.GetDirectory()))
860 return run_to_breakpoint_do_run(test, target, breakpoint, launch_info)
861
862
Kate Stoneb9c1b512016-09-06 20:57:50 +0000863def continue_to_breakpoint(process, bkpt):
Johnny Chend0fef812011-04-25 23:38:13 +0000864 """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None"""
865 process.Continue()
866 if process.GetState() != lldb.eStateStopped:
867 return None
868 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000869 return get_threads_stopped_at_breakpoint(process, bkpt)
870
Johnny Chend0fef812011-04-25 23:38:13 +0000871
Johnny Chena4603162011-03-09 23:45:56 +0000872def get_caller_symbol(thread):
873 """
874 Returns the symbol name for the call site of the leaf function.
875 """
876 depth = thread.GetNumFrames()
877 if depth <= 1:
878 return None
879 caller = thread.GetFrameAtIndex(1).GetSymbol()
880 if caller:
881 return caller.GetName()
882 else:
883 return None
884
885
Johnny Chend0fef812011-04-25 23:38:13 +0000886def get_function_names(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000887 """
888 Returns a sequence of function names from the stack frames of this thread.
889 """
890 def GetFuncName(i):
Johnny Chen4cfd07e2011-06-20 00:26:39 +0000891 return thread.GetFrameAtIndex(i).GetFunctionName()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000892
Zachary Turner744cd5d2015-10-26 16:49:57 +0000893 return list(map(GetFuncName, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000894
895
Johnny Chend0fef812011-04-25 23:38:13 +0000896def get_symbol_names(thread):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000897 """
898 Returns a sequence of symbols for this thread.
899 """
900 def GetSymbol(i):
901 return thread.GetFrameAtIndex(i).GetSymbol().GetName()
902
Zachary Turner744cd5d2015-10-26 16:49:57 +0000903 return list(map(GetSymbol, list(range(thread.GetNumFrames()))))
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000904
905
Johnny Chend0fef812011-04-25 23:38:13 +0000906def get_pc_addresses(thread):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000907 """
908 Returns a sequence of pc addresses for this thread.
909 """
910 def GetPCAddress(i):
911 return thread.GetFrameAtIndex(i).GetPCAddress()
912
Zachary Turner744cd5d2015-10-26 16:49:57 +0000913 return list(map(GetPCAddress, list(range(thread.GetNumFrames()))))
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000914
915
Johnny Chend0fef812011-04-25 23:38:13 +0000916def get_filenames(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000917 """
918 Returns a sequence of file names from the stack frames of this thread.
919 """
920 def GetFilename(i):
Kate Stoneb9c1b512016-09-06 20:57:50 +0000921 return thread.GetFrameAtIndex(
922 i).GetLineEntry().GetFileSpec().GetFilename()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000923
Zachary Turner744cd5d2015-10-26 16:49:57 +0000924 return list(map(GetFilename, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000925
926
Johnny Chend0fef812011-04-25 23:38:13 +0000927def get_line_numbers(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000928 """
929 Returns a sequence of line numbers from the stack frames of this thread.
930 """
931 def GetLineNumber(i):
932 return thread.GetFrameAtIndex(i).GetLineEntry().GetLine()
933
Zachary Turner744cd5d2015-10-26 16:49:57 +0000934 return list(map(GetLineNumber, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000935
936
Johnny Chend0fef812011-04-25 23:38:13 +0000937def get_module_names(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000938 """
939 Returns a sequence of module names from the stack frames of this thread.
940 """
941 def GetModuleName(i):
Kate Stoneb9c1b512016-09-06 20:57:50 +0000942 return thread.GetFrameAtIndex(
943 i).GetModule().GetFileSpec().GetFilename()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000944
Zachary Turner744cd5d2015-10-26 16:49:57 +0000945 return list(map(GetModuleName, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000946
947
Johnny Chend0fef812011-04-25 23:38:13 +0000948def get_stack_frames(thread):
Johnny Chen43a651c2010-09-09 00:55:07 +0000949 """
950 Returns a sequence of stack frames for this thread.
951 """
952 def GetStackFrame(i):
953 return thread.GetFrameAtIndex(i)
954
Zachary Turner744cd5d2015-10-26 16:49:57 +0000955 return list(map(GetStackFrame, list(range(thread.GetNumFrames()))))
Johnny Chen43a651c2010-09-09 00:55:07 +0000956
957
Kate Stoneb9c1b512016-09-06 20:57:50 +0000958def print_stacktrace(thread, string_buffer=False):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000959 """Prints a simple stack trace of this thread."""
Johnny Chen6c704992010-10-07 18:52:48 +0000960
Zachary Turner814236d2015-10-21 17:48:52 +0000961 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000962 target = thread.GetProcess().GetTarget()
963
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000964 depth = thread.GetNumFrames()
965
Johnny Chend0fef812011-04-25 23:38:13 +0000966 mods = get_module_names(thread)
967 funcs = get_function_names(thread)
968 symbols = get_symbol_names(thread)
969 files = get_filenames(thread)
970 lines = get_line_numbers(thread)
971 addrs = get_pc_addresses(thread)
Johnny Chen6c704992010-10-07 18:52:48 +0000972
Johnny Chen567a0452010-10-25 19:13:52 +0000973 if thread.GetStopReason() != lldb.eStopReasonInvalid:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000974 desc = "stop reason=" + stop_reason_to_str(thread.GetStopReason())
Johnny Chen567a0452010-10-25 19:13:52 +0000975 else:
976 desc = ""
Kate Stoneb9c1b512016-09-06 20:57:50 +0000977 print(
978 "Stack trace for thread id={0:#x} name={1} queue={2} ".format(
979 thread.GetThreadID(),
980 thread.GetName(),
981 thread.GetQueueName()) + desc,
982 file=output)
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000983
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000984 for i in range(depth):
985 frame = thread.GetFrameAtIndex(i)
986 function = frame.GetFunction()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000987
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000988 load_addr = addrs[i].GetLoadAddress(target)
Johnny Chen3cd1e552011-05-25 19:06:18 +0000989 if not function:
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000990 file_addr = addrs[i].GetFileAddress()
Johnny Chen0d4f6dd2011-06-16 22:07:48 +0000991 start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress()
992 symbol_offset = file_addr - start_addr
Kate Stoneb9c1b512016-09-06 20:57:50 +0000993 print(
994 " frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format(
995 num=i,
996 addr=load_addr,
997 mod=mods[i],
998 symbol=symbols[i],
999 offset=symbol_offset),
1000 file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +00001001 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001002 print(
1003 " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format(
1004 num=i,
1005 addr=load_addr,
1006 mod=mods[i],
1007 func='%s [inlined]' %
1008 funcs[i] if frame.IsInlined() else funcs[i],
1009 file=files[i],
1010 line=lines[i],
1011 args=get_args_as_string(
1012 frame,
1013 showFuncName=False) if not frame.IsInlined() else '()'),
1014 file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +00001015
1016 if string_buffer:
Johnny Chend5d6fac2010-10-15 23:33:18 +00001017 return output.getvalue()
Johnny Chen7ea9aee2010-10-07 21:38:28 +00001018
1019
Kate Stoneb9c1b512016-09-06 20:57:50 +00001020def print_stacktraces(process, string_buffer=False):
Johnny Chen7ea9aee2010-10-07 21:38:28 +00001021 """Prints the stack traces of all the threads."""
1022
Zachary Turner814236d2015-10-21 17:48:52 +00001023 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chen7ea9aee2010-10-07 21:38:28 +00001024
Zachary Turnerff890da2015-10-19 23:45:41 +00001025 print("Stack traces for " + str(process), file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +00001026
Johnny Chenae9639a2011-05-05 18:50:56 +00001027 for thread in process:
Zachary Turnerff890da2015-10-19 23:45:41 +00001028 print(print_stacktrace(thread, string_buffer=True), file=output)
Johnny Chen6c704992010-10-07 18:52:48 +00001029
1030 if string_buffer:
Johnny Chend5d6fac2010-10-15 23:33:18 +00001031 return output.getvalue()
Johnny Chenb21c52e2011-05-08 17:25:27 +00001032
Kate Stoneb9c1b512016-09-06 20:57:50 +00001033
1034def expect_state_changes(test, listener, process, states, timeout=5):
Pavel Labath5dcb0252015-09-02 09:12:28 +00001035 """Listens for state changed events on the listener and makes sure they match what we
1036 expect. Stop-and-restart events (where GetRestartedFromEvent() returns true) are ignored."""
Pavel Labathe5c98082016-01-06 11:40:06 +00001037
Pavel Labath5dcb0252015-09-02 09:12:28 +00001038 for expected_state in states:
Pavel Labathe5c98082016-01-06 11:40:06 +00001039 def get_next_event():
1040 event = lldb.SBEvent()
Kate Stoneb9c1b512016-09-06 20:57:50 +00001041 if not listener.WaitForEventForBroadcasterWithType(
1042 timeout,
1043 process.GetBroadcaster(),
1044 lldb.SBProcess.eBroadcastBitStateChanged,
1045 event):
1046 test.fail(
1047 "Timed out while waiting for a transition to state %s" %
Pavel Labathe5c98082016-01-06 11:40:06 +00001048 lldb.SBDebugger.StateAsCString(expected_state))
1049 return event
Pavel Labath5dcb0252015-09-02 09:12:28 +00001050
Pavel Labathe5c98082016-01-06 11:40:06 +00001051 event = get_next_event()
1052 while (lldb.SBProcess.GetStateFromEvent(event) == lldb.eStateStopped and
1053 lldb.SBProcess.GetRestartedFromEvent(event)):
1054 # Ignore restarted event and the subsequent running event.
1055 event = get_next_event()
Kate Stoneb9c1b512016-09-06 20:57:50 +00001056 test.assertEqual(
1057 lldb.SBProcess.GetStateFromEvent(event),
1058 lldb.eStateRunning,
1059 "Restarted event followed by a running event")
Pavel Labathe5c98082016-01-06 11:40:06 +00001060 event = get_next_event()
Pavel Labath5dcb0252015-09-02 09:12:28 +00001061
Kate Stoneb9c1b512016-09-06 20:57:50 +00001062 test.assertEqual(
1063 lldb.SBProcess.GetStateFromEvent(event),
1064 expected_state)
Pavel Labath5dcb0252015-09-02 09:12:28 +00001065
Johnny Chenb21c52e2011-05-08 17:25:27 +00001066# ===================================
1067# Utility functions related to Frames
1068# ===================================
1069
Kate Stoneb9c1b512016-09-06 20:57:50 +00001070
Johnny Chenad7372c2011-05-12 00:32:41 +00001071def get_parent_frame(frame):
1072 """
1073 Returns the parent frame of the input frame object; None if not available.
1074 """
1075 thread = frame.GetThread()
1076 parent_found = False
1077 for f in thread:
1078 if parent_found:
1079 return f
1080 if f.GetFrameID() == frame.GetFrameID():
1081 parent_found = True
1082
1083 # If we reach here, no parent has been found, return None.
1084 return None
1085
Kate Stoneb9c1b512016-09-06 20:57:50 +00001086
Johnny Chen0d4f6dd2011-06-16 22:07:48 +00001087def get_args_as_string(frame, showFuncName=True):
Johnny Chenad7372c2011-05-12 00:32:41 +00001088 """
1089 Returns the args of the input frame object as a string.
1090 """
1091 # arguments => True
1092 # locals => False
1093 # statics => False
1094 # in_scope_only => True
Kate Stoneb9c1b512016-09-06 20:57:50 +00001095 vars = frame.GetVariables(True, False, False, True) # type of SBValueList
1096 args = [] # list of strings
Johnny Chenad7372c2011-05-12 00:32:41 +00001097 for var in vars:
1098 args.append("(%s)%s=%s" % (var.GetTypeName(),
1099 var.GetName(),
Greg Claytonfe42ac42011-08-03 22:57:10 +00001100 var.GetValue()))
Johnny Chen3cd1e552011-05-25 19:06:18 +00001101 if frame.GetFunction():
Johnny Chen52b0ffd92011-05-13 00:44:49 +00001102 name = frame.GetFunction().GetName()
Johnny Chen3cd1e552011-05-25 19:06:18 +00001103 elif frame.GetSymbol():
Johnny Chen52b0ffd92011-05-13 00:44:49 +00001104 name = frame.GetSymbol().GetName()
1105 else:
1106 name = ""
Johnny Chen0d4f6dd2011-06-16 22:07:48 +00001107 if showFuncName:
1108 return "%s(%s)" % (name, ", ".join(args))
1109 else:
1110 return "(%s)" % (", ".join(args))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001111
1112
1113def print_registers(frame, string_buffer=False):
Johnny Chen2158b972011-05-08 18:55:37 +00001114 """Prints all the register sets of the frame."""
Johnny Chenb21c52e2011-05-08 17:25:27 +00001115
Zachary Turner814236d2015-10-21 17:48:52 +00001116 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chenb21c52e2011-05-08 17:25:27 +00001117
Zachary Turnerff890da2015-10-19 23:45:41 +00001118 print("Register sets for " + str(frame), file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +00001119
Kate Stoneb9c1b512016-09-06 20:57:50 +00001120 registerSet = frame.GetRegisters() # Return type of SBValueList.
1121 print("Frame registers (size of register set = %d):" %
1122 registerSet.GetSize(), file=output)
Johnny Chen64ff7e62011-05-10 19:21:13 +00001123 for value in registerSet:
Zachary Turner35d017f2015-10-23 17:04:29 +00001124 #print(value, file=output)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001125 print("%s (number of children = %d):" %
1126 (value.GetName(), value.GetNumChildren()), file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +00001127 for child in value:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001128 print(
1129 "Name: %s, Value: %s" %
1130 (child.GetName(),
1131 child.GetValue()),
1132 file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +00001133
1134 if string_buffer:
1135 return output.getvalue()
Johnny Chen64ff7e62011-05-10 19:21:13 +00001136
Kate Stoneb9c1b512016-09-06 20:57:50 +00001137
Johnny Chen64ff7e62011-05-10 19:21:13 +00001138def get_registers(frame, kind):
1139 """Returns the registers given the frame and the kind of registers desired.
1140
1141 Returns None if there's no such kind.
1142 """
Kate Stoneb9c1b512016-09-06 20:57:50 +00001143 registerSet = frame.GetRegisters() # Return type of SBValueList.
Johnny Chen64ff7e62011-05-10 19:21:13 +00001144 for value in registerSet:
1145 if kind.lower() in value.GetName().lower():
1146 return value
1147
1148 return None
1149
Kate Stoneb9c1b512016-09-06 20:57:50 +00001150
Johnny Chen64ff7e62011-05-10 19:21:13 +00001151def get_GPRs(frame):
1152 """Returns the general purpose registers of the frame as an SBValue.
1153
Johnny Chene9e86892011-05-10 23:01:44 +00001154 The returned SBValue object is iterable. An example:
1155 ...
1156 from lldbutil import get_GPRs
1157 regs = get_GPRs(frame)
1158 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +00001159 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +00001160 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +00001161 """
1162 return get_registers(frame, "general purpose")
1163
Kate Stoneb9c1b512016-09-06 20:57:50 +00001164
Johnny Chen64ff7e62011-05-10 19:21:13 +00001165def get_FPRs(frame):
1166 """Returns the floating point registers of the frame as an SBValue.
1167
Johnny Chene9e86892011-05-10 23:01:44 +00001168 The returned SBValue object is iterable. An example:
1169 ...
1170 from lldbutil import get_FPRs
1171 regs = get_FPRs(frame)
1172 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +00001173 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +00001174 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +00001175 """
1176 return get_registers(frame, "floating point")
1177
Kate Stoneb9c1b512016-09-06 20:57:50 +00001178
Johnny Chen64ff7e62011-05-10 19:21:13 +00001179def get_ESRs(frame):
1180 """Returns the exception state registers of the frame as an SBValue.
1181
Johnny Chene9e86892011-05-10 23:01:44 +00001182 The returned SBValue object is iterable. An example:
1183 ...
1184 from lldbutil import get_ESRs
1185 regs = get_ESRs(frame)
1186 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +00001187 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +00001188 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +00001189 """
1190 return get_registers(frame, "exception state")
Johnny Chen989b7ef2011-07-22 00:47:58 +00001191
Johnny Chenefee1cd2011-07-22 00:51:54 +00001192# ======================================
1193# Utility classes/functions for SBValues
1194# ======================================
Johnny Chen989b7ef2011-07-22 00:47:58 +00001195
Kate Stoneb9c1b512016-09-06 20:57:50 +00001196
Johnny Chen989b7ef2011-07-22 00:47:58 +00001197class BasicFormatter(object):
Johnny Chen36d7d912011-07-22 22:01:35 +00001198 """The basic formatter inspects the value object and prints the value."""
Kate Stoneb9c1b512016-09-06 20:57:50 +00001199
Johnny Chen989b7ef2011-07-22 00:47:58 +00001200 def format(self, value, buffer=None, indent=0):
1201 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +00001202 output = SixStringIO()
Johnny Chen989b7ef2011-07-22 00:47:58 +00001203 else:
1204 output = buffer
Johnny Chen36d7d912011-07-22 22:01:35 +00001205 # If there is a summary, it suffices.
1206 val = value.GetSummary()
1207 # Otherwise, get the value.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001208 if val is None:
Johnny Chen36d7d912011-07-22 22:01:35 +00001209 val = value.GetValue()
Kate Stoneb9c1b512016-09-06 20:57:50 +00001210 if val is None and value.GetNumChildren() > 0:
Johnny Chen36d7d912011-07-22 22:01:35 +00001211 val = "%s (location)" % value.GetLocation()
Zachary Turnerff890da2015-10-19 23:45:41 +00001212 print("{indentation}({type}) {name} = {value}".format(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001213 indentation=' ' * indent,
1214 type=value.GetTypeName(),
1215 name=value.GetName(),
1216 value=val), file=output)
Johnny Chen989b7ef2011-07-22 00:47:58 +00001217 return output.getvalue()
1218
Kate Stoneb9c1b512016-09-06 20:57:50 +00001219
Johnny Chen989b7ef2011-07-22 00:47:58 +00001220class ChildVisitingFormatter(BasicFormatter):
Johnny Chen36d7d912011-07-22 22:01:35 +00001221 """The child visiting formatter prints the value and its immediate children.
1222
1223 The constructor takes a keyword arg: indent_child, which defaults to 2.
1224 """
Kate Stoneb9c1b512016-09-06 20:57:50 +00001225
Johnny Chen36d7d912011-07-22 22:01:35 +00001226 def __init__(self, indent_child=2):
1227 """Default indentation of 2 SPC's for the children."""
1228 self.cindent = indent_child
Kate Stoneb9c1b512016-09-06 20:57:50 +00001229
Johnny Chen989b7ef2011-07-22 00:47:58 +00001230 def format(self, value, buffer=None):
1231 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +00001232 output = SixStringIO()
Johnny Chen989b7ef2011-07-22 00:47:58 +00001233 else:
1234 output = buffer
1235
1236 BasicFormatter.format(self, value, buffer=output)
1237 for child in value:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001238 BasicFormatter.format(
1239 self, child, buffer=output, indent=self.cindent)
Johnny Chen36d7d912011-07-22 22:01:35 +00001240
1241 return output.getvalue()
1242
Kate Stoneb9c1b512016-09-06 20:57:50 +00001243
Johnny Chen36d7d912011-07-22 22:01:35 +00001244class RecursiveDecentFormatter(BasicFormatter):
1245 """The recursive decent formatter prints the value and the decendents.
1246
1247 The constructor takes two keyword args: indent_level, which defaults to 0,
1248 and indent_child, which defaults to 2. The current indentation level is
1249 determined by indent_level, while the immediate children has an additional
Kate Stoneb9c1b512016-09-06 20:57:50 +00001250 indentation by inden_child.
Johnny Chen36d7d912011-07-22 22:01:35 +00001251 """
Kate Stoneb9c1b512016-09-06 20:57:50 +00001252
Johnny Chen36d7d912011-07-22 22:01:35 +00001253 def __init__(self, indent_level=0, indent_child=2):
1254 self.lindent = indent_level
1255 self.cindent = indent_child
Kate Stoneb9c1b512016-09-06 20:57:50 +00001256
Johnny Chen36d7d912011-07-22 22:01:35 +00001257 def format(self, value, buffer=None):
1258 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +00001259 output = SixStringIO()
Johnny Chen36d7d912011-07-22 22:01:35 +00001260 else:
1261 output = buffer
1262
1263 BasicFormatter.format(self, value, buffer=output, indent=self.lindent)
1264 new_indent = self.lindent + self.cindent
1265 for child in value:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001266 if child.GetSummary() is not None:
1267 BasicFormatter.format(
1268 self, child, buffer=output, indent=new_indent)
Johnny Chen36d7d912011-07-22 22:01:35 +00001269 else:
1270 if child.GetNumChildren() > 0:
1271 rdf = RecursiveDecentFormatter(indent_level=new_indent)
1272 rdf.format(child, buffer=output)
1273 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001274 BasicFormatter.format(
1275 self, child, buffer=output, indent=new_indent)
Johnny Chen989b7ef2011-07-22 00:47:58 +00001276
1277 return output.getvalue()
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001278
1279# ===========================================================
1280# Utility functions for path manipulation on remote platforms
1281# ===========================================================
1282
Kate Stoneb9c1b512016-09-06 20:57:50 +00001283
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001284def join_remote_paths(*paths):
1285 # TODO: update with actual platform name for remote windows once it exists
1286 if lldb.remote_platform.GetName() == 'remote-windows':
1287 return os.path.join(*paths).replace(os.path.sep, '\\')
1288 return os.path.join(*paths).replace(os.path.sep, '/')
1289
Kate Stoneb9c1b512016-09-06 20:57:50 +00001290
Pavel Labathf3a9ab02018-02-21 15:33:53 +00001291def append_to_process_working_directory(test, *paths):
Chaoren Lin5d76b1b2015-06-06 00:25:50 +00001292 remote = lldb.remote_platform
1293 if remote:
1294 return join_remote_paths(remote.GetWorkingDirectory(), *paths)
Pavel Labathf3a9ab02018-02-21 15:33:53 +00001295 return os.path.join(test.getBuildDir(), *paths)
Chaoren Linf59d05092015-06-02 16:46:28 +00001296
1297# ==================================================
1298# Utility functions to get the correct signal number
1299# ==================================================
1300
1301import signal
1302
Kate Stoneb9c1b512016-09-06 20:57:50 +00001303
Chaoren Linf59d05092015-06-02 16:46:28 +00001304def get_signal_number(signal_name):
1305 platform = lldb.remote_platform
Chaoren Lin98d0a4b2015-07-14 01:09:28 +00001306 if platform and platform.IsValid():
1307 signals = platform.GetUnixSignals()
1308 if signals.IsValid():
Chaoren Lin264e5422015-06-02 18:31:57 +00001309 signal_number = signals.GetSignalNumberFromName(signal_name)
1310 if signal_number > 0:
1311 return signal_number
Chaoren Lin98d0a4b2015-07-14 01:09:28 +00001312 # No remote platform; fall back to using local python signals.
Chaoren Linf59d05092015-06-02 16:46:28 +00001313 return getattr(signal, signal_name)
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001314
Kate Stoneb9c1b512016-09-06 20:57:50 +00001315
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001316class PrintableRegex(object):
Kate Stoneb9c1b512016-09-06 20:57:50 +00001317
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001318 def __init__(self, text):
1319 self.regex = re.compile(text)
1320 self.text = text
Kate Stoneb9c1b512016-09-06 20:57:50 +00001321
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001322 def match(self, str):
1323 return self.regex.match(str)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001324
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001325 def __str__(self):
1326 return "%s" % (self.text)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001327
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001328 def __repr__(self):
1329 return "re.compile(%s) -> %s" % (self.text, self.regex)
1330
Kate Stoneb9c1b512016-09-06 20:57:50 +00001331
Enrico Granataef4fa442015-12-04 19:50:05 +00001332def skip_if_callable(test, mycallable, reason):
1333 if six.callable(mycallable):
1334 if mycallable(test):
1335 test.skipTest(reason)
1336 return True
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001337 return False
1338
Kate Stoneb9c1b512016-09-06 20:57:50 +00001339
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001340def skip_if_library_missing(test, target, library):
1341 def find_library(target, library):
1342 for module in target.modules:
1343 filename = module.file.GetFilename()
1344 if isinstance(library, str):
1345 if library == filename:
1346 return False
1347 elif hasattr(library, 'match'):
1348 if library.match(filename):
1349 return False
1350 return True
Kate Stoneb9c1b512016-09-06 20:57:50 +00001351
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001352 def find_library_callable(test):
1353 return find_library(target, library)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001354 return skip_if_callable(
1355 test,
1356 find_library_callable,
1357 "could not find library matching '%s' in target %s" %
1358 (library,
1359 target))
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001360
Kate Stoneb9c1b512016-09-06 20:57:50 +00001361
Pavel Labath107052f2018-03-15 13:47:09 +00001362def read_file_on_target(test, remote):
1363 if lldb.remote_platform:
1364 local = test.getBuildArtifact("file_from_target")
1365 error = lldb.remote_platform.Get(lldb.SBFileSpec(remote, False),
1366 lldb.SBFileSpec(local, True))
1367 test.assertTrue(error.Success(), "Reading file {0} failed: {1}".format(remote, error))
1368 else:
1369 local = remote
1370 with open(local, 'r') as f:
1371 return f.read()
1372
1373def read_file_from_process_wd(test, name):
1374 path = append_to_process_working_directory(test, name)
1375 return read_file_on_target(test, path)
1376
Kate Stoneb9c1b512016-09-06 20:57:50 +00001377def wait_for_file_on_target(testcase, file_path, max_attempts=6):
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001378 for i in range(max_attempts):
1379 err, retcode, msg = testcase.run_platform_command("ls %s" % file_path)
1380 if err.Success() and retcode == 0:
1381 break
1382 if i < max_attempts:
1383 # Exponential backoff!
Todd Fiala464f7df2016-04-08 18:06:11 +00001384 import time
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001385 time.sleep(pow(2, i) * 0.25)
1386 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001387 testcase.fail(
1388 "File %s not found even after %d attempts." %
1389 (file_path, max_attempts))
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001390
Pavel Labath107052f2018-03-15 13:47:09 +00001391 return read_file_on_target(testcase, file_path)