blob: 45f23b565dd7970dd67436ea298dbb8ae27cb19a [file] [log] [blame]
Johnny Chen30ee4ef2010-09-08 22:54:46 +00001"""
Johnny Chen7ea9aee2010-10-07 21:38:28 +00002This LLDB module contains miscellaneous utilities.
Johnny Chenb411b982011-05-13 21:55:30 +00003Some of the test suite takes advantage of the utility functions defined here.
4They can also be useful for general purpose lldb scripting.
Johnny Chen30ee4ef2010-09-08 22:54:46 +00005"""
6
Zachary Turnerff890da2015-10-19 23:45:41 +00007from __future__ import print_function
Zachary Turnerc1b7cd72015-11-05 19:22:28 +00008from __future__ import absolute_import
Zachary Turnerff890da2015-10-19 23:45:41 +00009
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000010# System modules
11import collections
Adrian Prantl5ec76fe2018-01-30 18:29:16 +000012import errno
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000013import os
Enrico Granata0b5a6e32015-09-18 20:12:52 +000014import re
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000015import sys
Pavel Labatha95e0ef2016-04-06 08:55:31 +000016import time
Johnny Chen30ee4ef2010-09-08 22:54:46 +000017
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000018# Third-party modules
Zachary Turner814236d2015-10-21 17:48:52 +000019from six import StringIO as SixStringIO
Zachary Turnercd236b82015-10-26 18:48:24 +000020import six
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000021
22# LLDB modules
23import lldb
24
Zachary Turner814236d2015-10-21 17:48:52 +000025
Johnny Chen6424b7d2011-04-26 23:07:40 +000026# ===================================================
27# Utilities for locating/checking executable programs
28# ===================================================
Johnny Chen4fdcebd2011-04-26 22:53:38 +000029
Johnny Chenac77f3b2011-03-23 20:28:59 +000030def is_exe(fpath):
Johnny Chen35ec6742011-04-26 23:10:15 +000031 """Returns True if fpath is an executable."""
Johnny Chenac77f3b2011-03-23 20:28:59 +000032 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
33
Kate Stoneb9c1b512016-09-06 20:57:50 +000034
Johnny Chenac77f3b2011-03-23 20:28:59 +000035def which(program):
Johnny Chen35ec6742011-04-26 23:10:15 +000036 """Returns the full path to a program; None otherwise."""
Johnny Chenac77f3b2011-03-23 20:28:59 +000037 fpath, fname = os.path.split(program)
38 if fpath:
39 if is_exe(program):
40 return program
41 else:
42 for path in os.environ["PATH"].split(os.pathsep):
43 exe_file = os.path.join(path, program)
44 if is_exe(exe_file):
45 return exe_file
46 return None
47
Adrian Prantl5ec76fe2018-01-30 18:29:16 +000048def mkdir_p(path):
49 try:
50 os.makedirs(path)
51 except OSError as e:
52 if e.errno != errno.EEXIST:
53 raise
54 if not os.path.isdir(path):
55 raise OSError(errno.ENOTDIR, "%s is not a directory"%path)
Johnny Chened401982011-03-03 19:14:00 +000056# ===================================================
57# Disassembly for an SBFunction or an SBSymbol object
58# ===================================================
59
Kate Stoneb9c1b512016-09-06 20:57:50 +000060
Johnny Chened401982011-03-03 19:14:00 +000061def disassemble(target, function_or_symbol):
62 """Disassemble the function or symbol given a target.
63
64 It returns the disassembly content in a string object.
65 """
Zachary Turner814236d2015-10-21 17:48:52 +000066 buf = SixStringIO()
Johnny Chened401982011-03-03 19:14:00 +000067 insts = function_or_symbol.GetInstructions(target)
Johnny Chene69c7482011-04-28 22:57:01 +000068 for i in insts:
Zachary Turnerff890da2015-10-19 23:45:41 +000069 print(i, file=buf)
Johnny Chened401982011-03-03 19:14:00 +000070 return buf.getvalue()
71
Johnny Chen43766d62011-03-02 01:36:45 +000072# ==========================================================
73# Integer (byte size 1, 2, 4, and 8) to bytearray conversion
74# ==========================================================
75
Kate Stoneb9c1b512016-09-06 20:57:50 +000076
Johnny Chen43766d62011-03-02 01:36:45 +000077def int_to_bytearray(val, bytesize):
78 """Utility function to convert an integer into a bytearray.
79
Johnny Chen43e587c2011-03-02 20:54:22 +000080 It returns the bytearray in the little endian format. It is easy to get the
81 big endian format, just do ba.reverse() on the returned object.
Johnny Chen43766d62011-03-02 01:36:45 +000082 """
Johnny Chen90bb9052011-03-30 17:54:35 +000083 import struct
Johnny Chen43766d62011-03-02 01:36:45 +000084
85 if bytesize == 1:
86 return bytearray([val])
87
88 # Little endian followed by a format character.
89 template = "<%c"
90 if bytesize == 2:
91 fmt = template % 'h'
92 elif bytesize == 4:
93 fmt = template % 'i'
94 elif bytesize == 4:
95 fmt = template % 'q'
96 else:
97 return None
98
Johnny Chen90bb9052011-03-30 17:54:35 +000099 packed = struct.pack(fmt, val)
Zachary Turner44073962016-01-25 23:21:18 +0000100 return bytearray(packed)
Johnny Chen43766d62011-03-02 01:36:45 +0000101
Kate Stoneb9c1b512016-09-06 20:57:50 +0000102
Johnny Chen43766d62011-03-02 01:36:45 +0000103def bytearray_to_int(bytes, bytesize):
104 """Utility function to convert a bytearray into an integer.
105
Johnny Chen43e587c2011-03-02 20:54:22 +0000106 It interprets the bytearray in the little endian format. For a big endian
107 bytearray, just do ba.reverse() on the object before passing it in.
Johnny Chen43766d62011-03-02 01:36:45 +0000108 """
Johnny Chen90bb9052011-03-30 17:54:35 +0000109 import struct
Johnny Chen43766d62011-03-02 01:36:45 +0000110
111 if bytesize == 1:
Filipe Cabecinhas5d261b02012-07-06 16:20:13 +0000112 return bytes[0]
Johnny Chen43766d62011-03-02 01:36:45 +0000113
114 # Little endian followed by a format character.
115 template = "<%c"
116 if bytesize == 2:
117 fmt = template % 'h'
118 elif bytesize == 4:
119 fmt = template % 'i'
120 elif bytesize == 4:
121 fmt = template % 'q'
122 else:
123 return None
124
Zachary Turner44073962016-01-25 23:21:18 +0000125 unpacked = struct.unpack_from(fmt, bytes)
Johnny Chen43766d62011-03-02 01:36:45 +0000126 return unpacked[0]
127
128
Johnny Chen90256cd2011-04-23 00:13:34 +0000129# ==============================================================
130# Get the description of an lldb object or None if not available
131# ==============================================================
Johnny Chenfc87e2d2011-04-25 20:23:05 +0000132def get_description(obj, option=None):
133 """Calls lldb_obj.GetDescription() and returns a string, or None.
134
Johnny Chen01a67862011-10-14 00:42:25 +0000135 For SBTarget, SBBreakpointLocation, and SBWatchpoint lldb objects, an extra
136 option can be passed in to describe the detailed level of description
137 desired:
Johnny Chenfc87e2d2011-04-25 20:23:05 +0000138 o lldb.eDescriptionLevelBrief
139 o lldb.eDescriptionLevelFull
140 o lldb.eDescriptionLevelVerbose
141 """
142 method = getattr(obj, 'GetDescription')
Johnny Chen90256cd2011-04-23 00:13:34 +0000143 if not method:
144 return None
Johnny Chen01a67862011-10-14 00:42:25 +0000145 tuple = (lldb.SBTarget, lldb.SBBreakpointLocation, lldb.SBWatchpoint)
Johnny Chen469683e2011-09-27 21:27:19 +0000146 if isinstance(obj, tuple):
Johnny Chenfc87e2d2011-04-25 20:23:05 +0000147 if option is None:
148 option = lldb.eDescriptionLevelBrief
149
Johnny Chen90256cd2011-04-23 00:13:34 +0000150 stream = lldb.SBStream()
151 if option is None:
152 success = method(stream)
153 else:
154 success = method(stream, option)
155 if not success:
156 return None
157 return stream.GetData()
Kate Stoneb9c1b512016-09-06 20:57:50 +0000158
Johnny Chen90256cd2011-04-23 00:13:34 +0000159
Johnny Chenf4f70bb2010-10-22 21:31:03 +0000160# =================================================
161# Convert some enum value to its string counterpart
162# =================================================
Johnny Chen28ae2942010-10-07 22:15:58 +0000163
Johnny Chende90f1d2011-04-27 17:43:07 +0000164def state_type_to_str(enum):
Johnny Chen28ae2942010-10-07 22:15:58 +0000165 """Returns the stateType string given an enum."""
166 if enum == lldb.eStateInvalid:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000167 return "invalid"
Johnny Chen28ae2942010-10-07 22:15:58 +0000168 elif enum == lldb.eStateUnloaded:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000169 return "unloaded"
Johnny Chen930e3ad2011-03-05 01:20:11 +0000170 elif enum == lldb.eStateConnected:
171 return "connected"
Johnny Chen28ae2942010-10-07 22:15:58 +0000172 elif enum == lldb.eStateAttaching:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000173 return "attaching"
Johnny Chen28ae2942010-10-07 22:15:58 +0000174 elif enum == lldb.eStateLaunching:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000175 return "launching"
Johnny Chen28ae2942010-10-07 22:15:58 +0000176 elif enum == lldb.eStateStopped:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000177 return "stopped"
Johnny Chen28ae2942010-10-07 22:15:58 +0000178 elif enum == lldb.eStateRunning:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000179 return "running"
Johnny Chen28ae2942010-10-07 22:15:58 +0000180 elif enum == lldb.eStateStepping:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000181 return "stepping"
Johnny Chen28ae2942010-10-07 22:15:58 +0000182 elif enum == lldb.eStateCrashed:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000183 return "crashed"
Johnny Chen28ae2942010-10-07 22:15:58 +0000184 elif enum == lldb.eStateDetached:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000185 return "detached"
Johnny Chen28ae2942010-10-07 22:15:58 +0000186 elif enum == lldb.eStateExited:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000187 return "exited"
Johnny Chen28ae2942010-10-07 22:15:58 +0000188 elif enum == lldb.eStateSuspended:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000189 return "suspended"
Johnny Chen28ae2942010-10-07 22:15:58 +0000190 else:
Johnny Chen930e3ad2011-03-05 01:20:11 +0000191 raise Exception("Unknown StateType enum")
Johnny Chen28ae2942010-10-07 22:15:58 +0000192
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193
Johnny Chende90f1d2011-04-27 17:43:07 +0000194def stop_reason_to_str(enum):
Johnny Chen28ae2942010-10-07 22:15:58 +0000195 """Returns the stopReason string given an enum."""
196 if enum == lldb.eStopReasonInvalid:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000197 return "invalid"
Johnny Chen28ae2942010-10-07 22:15:58 +0000198 elif enum == lldb.eStopReasonNone:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000199 return "none"
Johnny Chen28ae2942010-10-07 22:15:58 +0000200 elif enum == lldb.eStopReasonTrace:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000201 return "trace"
Johnny Chen28ae2942010-10-07 22:15:58 +0000202 elif enum == lldb.eStopReasonBreakpoint:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000203 return "breakpoint"
Johnny Chen28ae2942010-10-07 22:15:58 +0000204 elif enum == lldb.eStopReasonWatchpoint:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000205 return "watchpoint"
Jim Ingham6cc0d2f2014-04-03 01:25:28 +0000206 elif enum == lldb.eStopReasonExec:
207 return "exec"
Johnny Chen28ae2942010-10-07 22:15:58 +0000208 elif enum == lldb.eStopReasonSignal:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000209 return "signal"
Johnny Chen28ae2942010-10-07 22:15:58 +0000210 elif enum == lldb.eStopReasonException:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000211 return "exception"
Johnny Chen28ae2942010-10-07 22:15:58 +0000212 elif enum == lldb.eStopReasonPlanComplete:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000213 return "plancomplete"
Daniel Maleab3d41a22013-07-09 00:08:01 +0000214 elif enum == lldb.eStopReasonThreadExiting:
215 return "threadexiting"
Johnny Chen28ae2942010-10-07 22:15:58 +0000216 else:
Johnny Chen930e3ad2011-03-05 01:20:11 +0000217 raise Exception("Unknown StopReason enum")
Johnny Chen28ae2942010-10-07 22:15:58 +0000218
Kate Stoneb9c1b512016-09-06 20:57:50 +0000219
Johnny Chena32a13d2011-09-28 00:51:00 +0000220def symbol_type_to_str(enum):
221 """Returns the symbolType string given an enum."""
222 if enum == lldb.eSymbolTypeInvalid:
223 return "invalid"
224 elif enum == lldb.eSymbolTypeAbsolute:
225 return "absolute"
Johnny Chena32a13d2011-09-28 00:51:00 +0000226 elif enum == lldb.eSymbolTypeCode:
227 return "code"
228 elif enum == lldb.eSymbolTypeData:
229 return "data"
230 elif enum == lldb.eSymbolTypeTrampoline:
231 return "trampoline"
232 elif enum == lldb.eSymbolTypeRuntime:
233 return "runtime"
234 elif enum == lldb.eSymbolTypeException:
235 return "exception"
236 elif enum == lldb.eSymbolTypeSourceFile:
237 return "sourcefile"
238 elif enum == lldb.eSymbolTypeHeaderFile:
239 return "headerfile"
240 elif enum == lldb.eSymbolTypeObjectFile:
241 return "objectfile"
242 elif enum == lldb.eSymbolTypeCommonBlock:
243 return "commonblock"
244 elif enum == lldb.eSymbolTypeBlock:
245 return "block"
246 elif enum == lldb.eSymbolTypeLocal:
247 return "local"
248 elif enum == lldb.eSymbolTypeParam:
249 return "param"
250 elif enum == lldb.eSymbolTypeVariable:
251 return "variable"
252 elif enum == lldb.eSymbolTypeVariableType:
253 return "variabletype"
254 elif enum == lldb.eSymbolTypeLineEntry:
255 return "lineentry"
256 elif enum == lldb.eSymbolTypeLineHeader:
257 return "lineheader"
258 elif enum == lldb.eSymbolTypeScopeBegin:
259 return "scopebegin"
260 elif enum == lldb.eSymbolTypeScopeEnd:
261 return "scopeend"
262 elif enum == lldb.eSymbolTypeAdditional:
263 return "additional"
264 elif enum == lldb.eSymbolTypeCompiler:
265 return "compiler"
266 elif enum == lldb.eSymbolTypeInstrumentation:
267 return "instrumentation"
268 elif enum == lldb.eSymbolTypeUndefined:
269 return "undefined"
270
Kate Stoneb9c1b512016-09-06 20:57:50 +0000271
Johnny Chende90f1d2011-04-27 17:43:07 +0000272def value_type_to_str(enum):
Johnny Chen87bb5892010-11-03 21:37:58 +0000273 """Returns the valueType string given an enum."""
274 if enum == lldb.eValueTypeInvalid:
275 return "invalid"
276 elif enum == lldb.eValueTypeVariableGlobal:
277 return "global_variable"
278 elif enum == lldb.eValueTypeVariableStatic:
279 return "static_variable"
280 elif enum == lldb.eValueTypeVariableArgument:
281 return "argument_variable"
282 elif enum == lldb.eValueTypeVariableLocal:
283 return "local_variable"
284 elif enum == lldb.eValueTypeRegister:
285 return "register"
286 elif enum == lldb.eValueTypeRegisterSet:
287 return "register_set"
288 elif enum == lldb.eValueTypeConstResult:
289 return "constant_result"
290 else:
Johnny Chen930e3ad2011-03-05 01:20:11 +0000291 raise Exception("Unknown ValueType enum")
Johnny Chen87bb5892010-11-03 21:37:58 +0000292
Johnny Chen28ae2942010-10-07 22:15:58 +0000293
Johnny Chenf4f70bb2010-10-22 21:31:03 +0000294# ==================================================
Daniel Maleab3d41a22013-07-09 00:08:01 +0000295# Get stopped threads due to each stop reason.
296# ==================================================
297
298def sort_stopped_threads(process,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000299 breakpoint_threads=None,
300 crashed_threads=None,
301 watchpoint_threads=None,
302 signal_threads=None,
303 exiting_threads=None,
304 other_threads=None):
Daniel Maleab3d41a22013-07-09 00:08:01 +0000305 """ Fills array *_threads with threads stopped for the corresponding stop
306 reason.
307 """
308 for lst in [breakpoint_threads,
309 watchpoint_threads,
310 signal_threads,
311 exiting_threads,
312 other_threads]:
313 if lst is not None:
314 lst[:] = []
315
316 for thread in process:
317 dispatched = False
318 for (reason, list) in [(lldb.eStopReasonBreakpoint, breakpoint_threads),
319 (lldb.eStopReasonException, crashed_threads),
320 (lldb.eStopReasonWatchpoint, watchpoint_threads),
321 (lldb.eStopReasonSignal, signal_threads),
322 (lldb.eStopReasonThreadExiting, exiting_threads),
323 (None, other_threads)]:
324 if not dispatched and list is not None:
325 if thread.GetStopReason() == reason or reason is None:
326 list.append(thread)
327 dispatched = True
328
329# ==================================================
Jim Ingham63dfc722012-09-22 00:05:11 +0000330# Utility functions for setting breakpoints
331# ==================================================
332
Kate Stoneb9c1b512016-09-06 20:57:50 +0000333
334def run_break_set_by_file_and_line(
335 test,
336 file_name,
337 line_number,
338 extra_options=None,
339 num_expected_locations=1,
340 loc_exact=False,
341 module_name=None):
342 """Set a breakpoint by file and line, returning the breakpoint number.
Jim Ingham63dfc722012-09-22 00:05:11 +0000343
344 If extra_options is not None, then we append it to the breakpoint set command.
345
346 If num_expected_locations is -1 we check that we got AT LEAST one location, otherwise we check that num_expected_locations equals the number of locations.
347
348 If loc_exact is true, we check that there is one location, and that location must be at the input file and line number."""
349
Kate Stoneb9c1b512016-09-06 20:57:50 +0000350 if file_name is None:
351 command = 'breakpoint set -l %d' % (line_number)
Jim Ingham63dfc722012-09-22 00:05:11 +0000352 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000353 command = 'breakpoint set -f "%s" -l %d' % (file_name, line_number)
Jim Ingham63dfc722012-09-22 00:05:11 +0000354
Greg Claytonc1b2ccf2013-01-08 00:01:36 +0000355 if module_name:
356 command += " --shlib '%s'" % (module_name)
357
Jim Ingham63dfc722012-09-22 00:05:11 +0000358 if extra_options:
359 command += " " + extra_options
360
Kate Stoneb9c1b512016-09-06 20:57:50 +0000361 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000362
363 if num_expected_locations == 1 and loc_exact:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000364 check_breakpoint_result(
365 test,
366 break_results,
367 num_locations=num_expected_locations,
368 file_name=file_name,
369 line_number=line_number,
370 module_name=module_name)
Jim Ingham63dfc722012-09-22 00:05:11 +0000371 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000372 check_breakpoint_result(
373 test,
374 break_results,
375 num_locations=num_expected_locations)
Jim Ingham63dfc722012-09-22 00:05:11 +0000376
Kate Stoneb9c1b512016-09-06 20:57:50 +0000377 return get_bpno_from_match(break_results)
Jim Ingham63dfc722012-09-22 00:05:11 +0000378
Kate Stoneb9c1b512016-09-06 20:57:50 +0000379
380def run_break_set_by_symbol(
381 test,
382 symbol,
383 extra_options=None,
384 num_expected_locations=-1,
385 sym_exact=False,
386 module_name=None):
Jim Ingham63dfc722012-09-22 00:05:11 +0000387 """Set a breakpoint by symbol name. Common options are the same as run_break_set_by_file_and_line.
388
389 If sym_exact is true, then the output symbol must match the input exactly, otherwise we do a substring match."""
Kate Stoneb9c1b512016-09-06 20:57:50 +0000390 command = 'breakpoint set -n "%s"' % (symbol)
Greg Claytonc1b2ccf2013-01-08 00:01:36 +0000391
392 if module_name:
393 command += " --shlib '%s'" % (module_name)
394
Jim Ingham63dfc722012-09-22 00:05:11 +0000395 if extra_options:
396 command += " " + extra_options
397
Kate Stoneb9c1b512016-09-06 20:57:50 +0000398 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000399
400 if num_expected_locations == 1 and sym_exact:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000401 check_breakpoint_result(
402 test,
403 break_results,
404 num_locations=num_expected_locations,
405 symbol_name=symbol,
406 module_name=module_name)
Jim Ingham63dfc722012-09-22 00:05:11 +0000407 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000408 check_breakpoint_result(
409 test,
410 break_results,
411 num_locations=num_expected_locations)
Jim Ingham63dfc722012-09-22 00:05:11 +0000412
Kate Stoneb9c1b512016-09-06 20:57:50 +0000413 return get_bpno_from_match(break_results)
Jim Ingham63dfc722012-09-22 00:05:11 +0000414
Kate Stoneb9c1b512016-09-06 20:57:50 +0000415
416def run_break_set_by_selector(
417 test,
418 selector,
419 extra_options=None,
420 num_expected_locations=-1,
421 module_name=None):
Jim Ingham63dfc722012-09-22 00:05:11 +0000422 """Set a breakpoint by selector. Common options are the same as run_break_set_by_file_and_line."""
423
Greg Claytonc1b2ccf2013-01-08 00:01:36 +0000424 command = 'breakpoint set -S "%s"' % (selector)
425
426 if module_name:
427 command += ' --shlib "%s"' % (module_name)
428
Jim Ingham63dfc722012-09-22 00:05:11 +0000429 if extra_options:
430 command += " " + extra_options
431
Kate Stoneb9c1b512016-09-06 20:57:50 +0000432 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000433
434 if num_expected_locations == 1:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000435 check_breakpoint_result(
436 test,
437 break_results,
438 num_locations=num_expected_locations,
439 symbol_name=selector,
440 symbol_match_exact=False,
441 module_name=module_name)
Jim Ingham63dfc722012-09-22 00:05:11 +0000442 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000443 check_breakpoint_result(
444 test,
445 break_results,
446 num_locations=num_expected_locations)
Jim Ingham63dfc722012-09-22 00:05:11 +0000447
Kate Stoneb9c1b512016-09-06 20:57:50 +0000448 return get_bpno_from_match(break_results)
Jim Ingham63dfc722012-09-22 00:05:11 +0000449
Kate Stoneb9c1b512016-09-06 20:57:50 +0000450
451def run_break_set_by_regexp(
452 test,
453 regexp,
454 extra_options=None,
455 num_expected_locations=-1):
Jim Ingham63dfc722012-09-22 00:05:11 +0000456 """Set a breakpoint by regular expression match on symbol name. Common options are the same as run_break_set_by_file_and_line."""
457
Kate Stoneb9c1b512016-09-06 20:57:50 +0000458 command = 'breakpoint set -r "%s"' % (regexp)
Jim Ingham63dfc722012-09-22 00:05:11 +0000459 if extra_options:
460 command += " " + extra_options
Jim Ingham63dfc722012-09-22 00:05:11 +0000461
Kate Stoneb9c1b512016-09-06 20:57:50 +0000462 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000463
Kate Stoneb9c1b512016-09-06 20:57:50 +0000464 check_breakpoint_result(
465 test,
466 break_results,
467 num_locations=num_expected_locations)
468
469 return get_bpno_from_match(break_results)
470
471
472def run_break_set_by_source_regexp(
473 test,
474 regexp,
475 extra_options=None,
476 num_expected_locations=-1):
Jim Ingham63dfc722012-09-22 00:05:11 +0000477 """Set a breakpoint by source regular expression. Common options are the same as run_break_set_by_file_and_line."""
Kate Stoneb9c1b512016-09-06 20:57:50 +0000478 command = 'breakpoint set -p "%s"' % (regexp)
Jim Ingham63dfc722012-09-22 00:05:11 +0000479 if extra_options:
480 command += " " + extra_options
Jim Ingham63dfc722012-09-22 00:05:11 +0000481
Kate Stoneb9c1b512016-09-06 20:57:50 +0000482 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000483
Kate Stoneb9c1b512016-09-06 20:57:50 +0000484 check_breakpoint_result(
485 test,
486 break_results,
487 num_locations=num_expected_locations)
488
489 return get_bpno_from_match(break_results)
490
491
492def run_break_set_command(test, command):
493 """Run the command passed in - it must be some break set variant - and analyze the result.
Jim Ingham63dfc722012-09-22 00:05:11 +0000494 Returns a dictionary of information gleaned from the command-line results.
495 Will assert if the breakpoint setting fails altogether.
496
497 Dictionary will contain:
498 bpno - breakpoint of the newly created breakpoint, -1 on error.
499 num_locations - number of locations set for the breakpoint.
500
501 If there is only one location, the dictionary MAY contain:
502 file - source file name
503 line_no - source line number
504 symbol - symbol name
505 inline_symbol - inlined symbol name
506 offset - offset from the original symbol
507 module - module
508 address - address at which the breakpoint was set."""
509
Kate Stoneb9c1b512016-09-06 20:57:50 +0000510 patterns = [
511 r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>[0-9]+) locations\.$",
512 r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>no) locations \(pending\)\.",
513 r"^Breakpoint (?P<bpno>[0-9]+): where = (?P<module>.*)`(?P<symbol>[+\-]{0,1}[^+]+)( \+ (?P<offset>[0-9]+)){0,1}( \[inlined\] (?P<inline_symbol>.*)){0,1} at (?P<file>[^:]+):(?P<line_no>[0-9]+), address = (?P<address>0x[0-9a-fA-F]+)$",
514 r"^Breakpoint (?P<bpno>[0-9]+): where = (?P<module>.*)`(?P<symbol>.*)( \+ (?P<offset>[0-9]+)){0,1}, address = (?P<address>0x[0-9a-fA-F]+)$"]
515 match_object = test.match(command, patterns)
Jim Ingham63dfc722012-09-22 00:05:11 +0000516 break_results = match_object.groupdict()
Jim Ingham63dfc722012-09-22 00:05:11 +0000517
518 # We always insert the breakpoint number, setting it to -1 if we couldn't find it
519 # Also, make sure it gets stored as an integer.
520 if not 'bpno' in break_results:
521 break_results['bpno'] = -1
522 else:
523 break_results['bpno'] = int(break_results['bpno'])
Kate Stoneb9c1b512016-09-06 20:57:50 +0000524
Jim Ingham63dfc722012-09-22 00:05:11 +0000525 # We always insert the number of locations
526 # If ONE location is set for the breakpoint, then the output doesn't mention locations, but it has to be 1...
527 # We also make sure it is an integer.
528
529 if not 'num_locations' in break_results:
530 num_locations = 1
531 else:
532 num_locations = break_results['num_locations']
533 if num_locations == 'no':
534 num_locations = 0
535 else:
536 num_locations = int(break_results['num_locations'])
537
538 break_results['num_locations'] = num_locations
Kate Stoneb9c1b512016-09-06 20:57:50 +0000539
Jim Ingham63dfc722012-09-22 00:05:11 +0000540 if 'line_no' in break_results:
541 break_results['line_no'] = int(break_results['line_no'])
542
543 return break_results
544
Jim Ingham63dfc722012-09-22 00:05:11 +0000545
Kate Stoneb9c1b512016-09-06 20:57:50 +0000546def get_bpno_from_match(break_results):
547 return int(break_results['bpno'])
548
549
550def check_breakpoint_result(
551 test,
552 break_results,
553 file_name=None,
554 line_number=-1,
555 symbol_name=None,
556 symbol_match_exact=True,
557 module_name=None,
558 offset=-1,
559 num_locations=-1):
Jim Ingham63dfc722012-09-22 00:05:11 +0000560
561 out_num_locations = break_results['num_locations']
562
Jim Ingham63dfc722012-09-22 00:05:11 +0000563 if num_locations == -1:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000564 test.assertTrue(out_num_locations > 0,
565 "Expecting one or more locations, got none.")
Jim Ingham63dfc722012-09-22 00:05:11 +0000566 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000567 test.assertTrue(
568 num_locations == out_num_locations,
569 "Expecting %d locations, got %d." %
570 (num_locations,
571 out_num_locations))
Jim Ingham63dfc722012-09-22 00:05:11 +0000572
573 if file_name:
574 out_file_name = ""
575 if 'file' in break_results:
576 out_file_name = break_results['file']
Kate Stoneb9c1b512016-09-06 20:57:50 +0000577 test.assertTrue(
578 file_name == out_file_name,
579 "Breakpoint file name '%s' doesn't match resultant name '%s'." %
580 (file_name,
581 out_file_name))
Jim Ingham63dfc722012-09-22 00:05:11 +0000582
583 if line_number != -1:
Ilia K055ad9b2015-05-18 13:41:01 +0000584 out_line_number = -1
Jim Ingham63dfc722012-09-22 00:05:11 +0000585 if 'line_no' in break_results:
586 out_line_number = break_results['line_no']
587
Kate Stoneb9c1b512016-09-06 20:57:50 +0000588 test.assertTrue(
589 line_number == out_line_number,
590 "Breakpoint line number %s doesn't match resultant line %s." %
591 (line_number,
592 out_line_number))
Jim Ingham63dfc722012-09-22 00:05:11 +0000593
594 if symbol_name:
595 out_symbol_name = ""
Kate Stoneb9c1b512016-09-06 20:57:50 +0000596 # Look first for the inlined symbol name, otherwise use the symbol
597 # name:
Jim Ingham63dfc722012-09-22 00:05:11 +0000598 if 'inline_symbol' in break_results and break_results['inline_symbol']:
599 out_symbol_name = break_results['inline_symbol']
600 elif 'symbol' in break_results:
601 out_symbol_name = break_results['symbol']
602
603 if symbol_match_exact:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000604 test.assertTrue(
605 symbol_name == out_symbol_name,
606 "Symbol name '%s' doesn't match resultant symbol '%s'." %
607 (symbol_name,
608 out_symbol_name))
Jim Ingham63dfc722012-09-22 00:05:11 +0000609 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000610 test.assertTrue(
611 out_symbol_name.find(symbol_name) != -
612 1,
613 "Symbol name '%s' isn't in resultant symbol '%s'." %
614 (symbol_name,
615 out_symbol_name))
Jim Ingham63dfc722012-09-22 00:05:11 +0000616
617 if module_name:
Ilia K055ad9b2015-05-18 13:41:01 +0000618 out_module_name = None
Jim Ingham63dfc722012-09-22 00:05:11 +0000619 if 'module' in break_results:
620 out_module_name = break_results['module']
Kate Stoneb9c1b512016-09-06 20:57:50 +0000621
622 test.assertTrue(
623 module_name.find(out_module_name) != -
624 1,
625 "Symbol module name '%s' isn't in expected module name '%s'." %
626 (out_module_name,
627 module_name))
Jim Ingham63dfc722012-09-22 00:05:11 +0000628
629# ==================================================
Johnny Chenf4f70bb2010-10-22 21:31:03 +0000630# Utility functions related to Threads and Processes
631# ==================================================
Johnny Chen28ae2942010-10-07 22:15:58 +0000632
Kate Stoneb9c1b512016-09-06 20:57:50 +0000633
Johnny Chend3699082011-04-25 22:04:05 +0000634def get_stopped_threads(process, reason):
Johnny Chen75ec1592011-05-26 21:53:05 +0000635 """Returns the thread(s) with the specified stop reason in a list.
636
637 The list can be empty if no such thread exists.
638 """
Johnny Chend3699082011-04-25 22:04:05 +0000639 threads = []
Johnny Chene69c7482011-04-28 22:57:01 +0000640 for t in process:
Johnny Chend3699082011-04-25 22:04:05 +0000641 if t.GetStopReason() == reason:
642 threads.append(t)
643 return threads
644
Kate Stoneb9c1b512016-09-06 20:57:50 +0000645
Johnny Chend3699082011-04-25 22:04:05 +0000646def get_stopped_thread(process, reason):
647 """A convenience function which returns the first thread with the given stop
648 reason or None.
649
650 Example usages:
651
652 1. Get the stopped thread due to a breakpoint condition
653
654 ...
655 from lldbutil import get_stopped_thread
Johnny Chen5a0bee72011-06-15 22:14:12 +0000656 thread = get_stopped_thread(process, lldb.eStopReasonPlanComplete)
Greg Clayton53c5ddf2013-03-19 17:59:30 +0000657 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition")
Johnny Chend3699082011-04-25 22:04:05 +0000658 ...
659
660 2. Get the thread stopped due to a breakpoint
661
662 ...
663 from lldbutil import get_stopped_thread
Johnny Chen5a0bee72011-06-15 22:14:12 +0000664 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
Greg Clayton53c5ddf2013-03-19 17:59:30 +0000665 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint")
Johnny Chend3699082011-04-25 22:04:05 +0000666 ...
667
668 """
669 threads = get_stopped_threads(process, reason)
670 if len(threads) == 0:
671 return None
672 return threads[0]
673
Kate Stoneb9c1b512016-09-06 20:57:50 +0000674
Zachary Turner1da094a2016-01-22 23:54:41 +0000675def get_threads_stopped_at_breakpoint_id(process, bpid):
Johnny Chend0fef812011-04-25 23:38:13 +0000676 """ For a stopped process returns the thread stopped at the breakpoint passed in bkpt"""
677 stopped_threads = []
678 threads = []
679
Kate Stoneb9c1b512016-09-06 20:57:50 +0000680 stopped_threads = get_stopped_threads(process, lldb.eStopReasonBreakpoint)
Johnny Chend0fef812011-04-25 23:38:13 +0000681
682 if len(stopped_threads) == 0:
683 return threads
Kate Stoneb9c1b512016-09-06 20:57:50 +0000684
Johnny Chend0fef812011-04-25 23:38:13 +0000685 for thread in stopped_threads:
Johnny Chen32391242011-12-22 20:21:46 +0000686 # Make sure we've hit our breakpoint...
Kate Stoneb9c1b512016-09-06 20:57:50 +0000687 break_id = thread.GetStopReasonDataAtIndex(0)
Zachary Turner1da094a2016-01-22 23:54:41 +0000688 if break_id == bpid:
Johnny Chend0fef812011-04-25 23:38:13 +0000689 threads.append(thread)
690
691 return threads
692
Kate Stoneb9c1b512016-09-06 20:57:50 +0000693
694def get_threads_stopped_at_breakpoint(process, bkpt):
Zachary Turner1da094a2016-01-22 23:54:41 +0000695 return get_threads_stopped_at_breakpoint_id(process, bkpt.GetID())
696
Kate Stoneb9c1b512016-09-06 20:57:50 +0000697
698def get_one_thread_stopped_at_breakpoint_id(
699 process, bpid, require_exactly_one=True):
Zachary Turner1da094a2016-01-22 23:54:41 +0000700 threads = get_threads_stopped_at_breakpoint_id(process, bpid)
Zachary Turner783550b2016-01-21 21:07:30 +0000701 if len(threads) == 0:
702 return None
703 if require_exactly_one and len(threads) != 1:
704 return None
705
706 return threads[0]
707
Zachary Turner1da094a2016-01-22 23:54:41 +0000708
Kate Stoneb9c1b512016-09-06 20:57:50 +0000709def get_one_thread_stopped_at_breakpoint(
710 process, bkpt, require_exactly_one=True):
711 return get_one_thread_stopped_at_breakpoint_id(
712 process, bkpt.GetID(), require_exactly_one)
713
714
715def is_thread_crashed(test, thread):
Pavel Labathc4e25c92015-05-29 10:13:03 +0000716 """In the test suite we dereference a null pointer to simulate a crash. The way this is
717 reported depends on the platform."""
718 if test.platformIsDarwin():
Kate Stoneb9c1b512016-09-06 20:57:50 +0000719 return thread.GetStopReason(
720 ) == lldb.eStopReasonException and "EXC_BAD_ACCESS" in thread.GetStopDescription(100)
Pavel Labathc4e25c92015-05-29 10:13:03 +0000721 elif test.getPlatform() == "linux":
Kate Stoneb9c1b512016-09-06 20:57:50 +0000722 return thread.GetStopReason() == lldb.eStopReasonSignal and thread.GetStopReasonDataAtIndex(
723 0) == thread.GetProcess().GetUnixSignals().GetSignalNumberFromName("SIGSEGV")
Pavel Labathc4e25c92015-05-29 10:13:03 +0000724 else:
725 return "invalid address" in thread.GetStopDescription(100)
726
Kate Stoneb9c1b512016-09-06 20:57:50 +0000727
728def get_crashed_threads(test, process):
Pavel Labathc4e25c92015-05-29 10:13:03 +0000729 threads = []
730 if process.GetState() != lldb.eStateStopped:
731 return threads
732 for thread in process:
733 if is_thread_crashed(test, thread):
734 threads.append(thread)
735 return threads
736
Adrian Prantl595048f2018-01-19 23:24:35 +0000737def run_to_source_breakpoint(test, bkpt_pattern, source_spec,
738 launch_info = None, exe_name = "a.out",
739 in_cwd = True):
740 """Start up a target, using exe_name as the executable, and run it to
Jim Inghama15e7f22017-07-06 02:18:16 +0000741 a breakpoint set by source regex bkpt_pattern.
Adrian Prantl595048f2018-01-19 23:24:35 +0000742
743 If you want to pass in launch arguments or environment
744 variables, you can optionally pass in an SBLaunchInfo. If you
745 do that, remember to set the working directory as well.
746
747 If your executable isn't called a.out, you can pass that in.
748 And if your executable isn't in the CWD, pass in the absolute
749 path to the executable in exe_name, and set in_cwd to False.
750
Jim Inghama15e7f22017-07-06 02:18:16 +0000751 If the target isn't valid, the breakpoint isn't found, or hit, the
752 function will cause a testsuite failure.
Adrian Prantl595048f2018-01-19 23:24:35 +0000753
754 If successful it returns a tuple with the target process and
755 thread that hit the breakpoint.
756 """
Jim Inghama15e7f22017-07-06 02:18:16 +0000757
758 if in_cwd:
Adrian Prantl595048f2018-01-19 23:24:35 +0000759 exe = test.getBuildArtifact(exe_name)
Jim Inghama15e7f22017-07-06 02:18:16 +0000760
761 # Create the target
762 target = test.dbg.CreateTarget(exe)
763 test.assertTrue(target, "Target: %s is not valid."%(exe_name))
764
765 # Set the breakpoints
766 breakpoint = target.BreakpointCreateBySourceRegex(
767 bkpt_pattern, source_spec)
768 test.assertTrue(breakpoint.GetNumLocations() > 0,
Adrian Prantlee2d2bf2018-01-30 19:40:09 +0000769 'No locations found for source breakpoint: "%s", file: "%s", dir: "%s"'%(bkpt_pattern, source_spec.GetFilename(), source_spec.GetDirectory()))
Jim Inghama15e7f22017-07-06 02:18:16 +0000770
771 # Launch the process, and do not stop at the entry point.
772 if not launch_info:
773 launch_info = lldb.SBLaunchInfo(None)
774 launch_info.SetWorkingDirectory(test.get_process_working_directory())
775
776 error = lldb.SBError()
777 process = target.Launch(launch_info, error)
778
779 test.assertTrue(process, "Could not create a valid process for %s: %s"%(exe_name, error.GetCString()))
780
781 # Frame #0 should be at our breakpoint.
782 threads = get_threads_stopped_at_breakpoint(
783 process, breakpoint)
784
785 test.assertTrue(len(threads) == 1, "Expected 1 thread to stop at breakpoint, %d did."%(len(threads)))
786 thread = threads[0]
787 return (target, process, thread, breakpoint)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000788
789def continue_to_breakpoint(process, bkpt):
Johnny Chend0fef812011-04-25 23:38:13 +0000790 """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None"""
791 process.Continue()
792 if process.GetState() != lldb.eStateStopped:
793 return None
794 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000795 return get_threads_stopped_at_breakpoint(process, bkpt)
796
Johnny Chend0fef812011-04-25 23:38:13 +0000797
Johnny Chena4603162011-03-09 23:45:56 +0000798def get_caller_symbol(thread):
799 """
800 Returns the symbol name for the call site of the leaf function.
801 """
802 depth = thread.GetNumFrames()
803 if depth <= 1:
804 return None
805 caller = thread.GetFrameAtIndex(1).GetSymbol()
806 if caller:
807 return caller.GetName()
808 else:
809 return None
810
811
Johnny Chend0fef812011-04-25 23:38:13 +0000812def get_function_names(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000813 """
814 Returns a sequence of function names from the stack frames of this thread.
815 """
816 def GetFuncName(i):
Johnny Chen4cfd07e2011-06-20 00:26:39 +0000817 return thread.GetFrameAtIndex(i).GetFunctionName()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000818
Zachary Turner744cd5d2015-10-26 16:49:57 +0000819 return list(map(GetFuncName, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000820
821
Johnny Chend0fef812011-04-25 23:38:13 +0000822def get_symbol_names(thread):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000823 """
824 Returns a sequence of symbols for this thread.
825 """
826 def GetSymbol(i):
827 return thread.GetFrameAtIndex(i).GetSymbol().GetName()
828
Zachary Turner744cd5d2015-10-26 16:49:57 +0000829 return list(map(GetSymbol, list(range(thread.GetNumFrames()))))
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000830
831
Johnny Chend0fef812011-04-25 23:38:13 +0000832def get_pc_addresses(thread):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000833 """
834 Returns a sequence of pc addresses for this thread.
835 """
836 def GetPCAddress(i):
837 return thread.GetFrameAtIndex(i).GetPCAddress()
838
Zachary Turner744cd5d2015-10-26 16:49:57 +0000839 return list(map(GetPCAddress, list(range(thread.GetNumFrames()))))
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000840
841
Johnny Chend0fef812011-04-25 23:38:13 +0000842def get_filenames(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000843 """
844 Returns a sequence of file names from the stack frames of this thread.
845 """
846 def GetFilename(i):
Kate Stoneb9c1b512016-09-06 20:57:50 +0000847 return thread.GetFrameAtIndex(
848 i).GetLineEntry().GetFileSpec().GetFilename()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000849
Zachary Turner744cd5d2015-10-26 16:49:57 +0000850 return list(map(GetFilename, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000851
852
Johnny Chend0fef812011-04-25 23:38:13 +0000853def get_line_numbers(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000854 """
855 Returns a sequence of line numbers from the stack frames of this thread.
856 """
857 def GetLineNumber(i):
858 return thread.GetFrameAtIndex(i).GetLineEntry().GetLine()
859
Zachary Turner744cd5d2015-10-26 16:49:57 +0000860 return list(map(GetLineNumber, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000861
862
Johnny Chend0fef812011-04-25 23:38:13 +0000863def get_module_names(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000864 """
865 Returns a sequence of module names from the stack frames of this thread.
866 """
867 def GetModuleName(i):
Kate Stoneb9c1b512016-09-06 20:57:50 +0000868 return thread.GetFrameAtIndex(
869 i).GetModule().GetFileSpec().GetFilename()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000870
Zachary Turner744cd5d2015-10-26 16:49:57 +0000871 return list(map(GetModuleName, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000872
873
Johnny Chend0fef812011-04-25 23:38:13 +0000874def get_stack_frames(thread):
Johnny Chen43a651c2010-09-09 00:55:07 +0000875 """
876 Returns a sequence of stack frames for this thread.
877 """
878 def GetStackFrame(i):
879 return thread.GetFrameAtIndex(i)
880
Zachary Turner744cd5d2015-10-26 16:49:57 +0000881 return list(map(GetStackFrame, list(range(thread.GetNumFrames()))))
Johnny Chen43a651c2010-09-09 00:55:07 +0000882
883
Kate Stoneb9c1b512016-09-06 20:57:50 +0000884def print_stacktrace(thread, string_buffer=False):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000885 """Prints a simple stack trace of this thread."""
Johnny Chen6c704992010-10-07 18:52:48 +0000886
Zachary Turner814236d2015-10-21 17:48:52 +0000887 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000888 target = thread.GetProcess().GetTarget()
889
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000890 depth = thread.GetNumFrames()
891
Johnny Chend0fef812011-04-25 23:38:13 +0000892 mods = get_module_names(thread)
893 funcs = get_function_names(thread)
894 symbols = get_symbol_names(thread)
895 files = get_filenames(thread)
896 lines = get_line_numbers(thread)
897 addrs = get_pc_addresses(thread)
Johnny Chen6c704992010-10-07 18:52:48 +0000898
Johnny Chen567a0452010-10-25 19:13:52 +0000899 if thread.GetStopReason() != lldb.eStopReasonInvalid:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000900 desc = "stop reason=" + stop_reason_to_str(thread.GetStopReason())
Johnny Chen567a0452010-10-25 19:13:52 +0000901 else:
902 desc = ""
Kate Stoneb9c1b512016-09-06 20:57:50 +0000903 print(
904 "Stack trace for thread id={0:#x} name={1} queue={2} ".format(
905 thread.GetThreadID(),
906 thread.GetName(),
907 thread.GetQueueName()) + desc,
908 file=output)
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000909
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000910 for i in range(depth):
911 frame = thread.GetFrameAtIndex(i)
912 function = frame.GetFunction()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000913
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000914 load_addr = addrs[i].GetLoadAddress(target)
Johnny Chen3cd1e552011-05-25 19:06:18 +0000915 if not function:
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000916 file_addr = addrs[i].GetFileAddress()
Johnny Chen0d4f6dd2011-06-16 22:07:48 +0000917 start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress()
918 symbol_offset = file_addr - start_addr
Kate Stoneb9c1b512016-09-06 20:57:50 +0000919 print(
920 " frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format(
921 num=i,
922 addr=load_addr,
923 mod=mods[i],
924 symbol=symbols[i],
925 offset=symbol_offset),
926 file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000927 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000928 print(
929 " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format(
930 num=i,
931 addr=load_addr,
932 mod=mods[i],
933 func='%s [inlined]' %
934 funcs[i] if frame.IsInlined() else funcs[i],
935 file=files[i],
936 line=lines[i],
937 args=get_args_as_string(
938 frame,
939 showFuncName=False) if not frame.IsInlined() else '()'),
940 file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000941
942 if string_buffer:
Johnny Chend5d6fac2010-10-15 23:33:18 +0000943 return output.getvalue()
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000944
945
Kate Stoneb9c1b512016-09-06 20:57:50 +0000946def print_stacktraces(process, string_buffer=False):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000947 """Prints the stack traces of all the threads."""
948
Zachary Turner814236d2015-10-21 17:48:52 +0000949 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000950
Zachary Turnerff890da2015-10-19 23:45:41 +0000951 print("Stack traces for " + str(process), file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000952
Johnny Chenae9639a2011-05-05 18:50:56 +0000953 for thread in process:
Zachary Turnerff890da2015-10-19 23:45:41 +0000954 print(print_stacktrace(thread, string_buffer=True), file=output)
Johnny Chen6c704992010-10-07 18:52:48 +0000955
956 if string_buffer:
Johnny Chend5d6fac2010-10-15 23:33:18 +0000957 return output.getvalue()
Johnny Chenb21c52e2011-05-08 17:25:27 +0000958
Kate Stoneb9c1b512016-09-06 20:57:50 +0000959
960def expect_state_changes(test, listener, process, states, timeout=5):
Pavel Labath5dcb0252015-09-02 09:12:28 +0000961 """Listens for state changed events on the listener and makes sure they match what we
962 expect. Stop-and-restart events (where GetRestartedFromEvent() returns true) are ignored."""
Pavel Labathe5c98082016-01-06 11:40:06 +0000963
Pavel Labath5dcb0252015-09-02 09:12:28 +0000964 for expected_state in states:
Pavel Labathe5c98082016-01-06 11:40:06 +0000965 def get_next_event():
966 event = lldb.SBEvent()
Kate Stoneb9c1b512016-09-06 20:57:50 +0000967 if not listener.WaitForEventForBroadcasterWithType(
968 timeout,
969 process.GetBroadcaster(),
970 lldb.SBProcess.eBroadcastBitStateChanged,
971 event):
972 test.fail(
973 "Timed out while waiting for a transition to state %s" %
Pavel Labathe5c98082016-01-06 11:40:06 +0000974 lldb.SBDebugger.StateAsCString(expected_state))
975 return event
Pavel Labath5dcb0252015-09-02 09:12:28 +0000976
Pavel Labathe5c98082016-01-06 11:40:06 +0000977 event = get_next_event()
978 while (lldb.SBProcess.GetStateFromEvent(event) == lldb.eStateStopped and
979 lldb.SBProcess.GetRestartedFromEvent(event)):
980 # Ignore restarted event and the subsequent running event.
981 event = get_next_event()
Kate Stoneb9c1b512016-09-06 20:57:50 +0000982 test.assertEqual(
983 lldb.SBProcess.GetStateFromEvent(event),
984 lldb.eStateRunning,
985 "Restarted event followed by a running event")
Pavel Labathe5c98082016-01-06 11:40:06 +0000986 event = get_next_event()
Pavel Labath5dcb0252015-09-02 09:12:28 +0000987
Kate Stoneb9c1b512016-09-06 20:57:50 +0000988 test.assertEqual(
989 lldb.SBProcess.GetStateFromEvent(event),
990 expected_state)
Pavel Labath5dcb0252015-09-02 09:12:28 +0000991
Johnny Chenb21c52e2011-05-08 17:25:27 +0000992# ===================================
993# Utility functions related to Frames
994# ===================================
995
Kate Stoneb9c1b512016-09-06 20:57:50 +0000996
Johnny Chenad7372c2011-05-12 00:32:41 +0000997def get_parent_frame(frame):
998 """
999 Returns the parent frame of the input frame object; None if not available.
1000 """
1001 thread = frame.GetThread()
1002 parent_found = False
1003 for f in thread:
1004 if parent_found:
1005 return f
1006 if f.GetFrameID() == frame.GetFrameID():
1007 parent_found = True
1008
1009 # If we reach here, no parent has been found, return None.
1010 return None
1011
Kate Stoneb9c1b512016-09-06 20:57:50 +00001012
Johnny Chen0d4f6dd2011-06-16 22:07:48 +00001013def get_args_as_string(frame, showFuncName=True):
Johnny Chenad7372c2011-05-12 00:32:41 +00001014 """
1015 Returns the args of the input frame object as a string.
1016 """
1017 # arguments => True
1018 # locals => False
1019 # statics => False
1020 # in_scope_only => True
Kate Stoneb9c1b512016-09-06 20:57:50 +00001021 vars = frame.GetVariables(True, False, False, True) # type of SBValueList
1022 args = [] # list of strings
Johnny Chenad7372c2011-05-12 00:32:41 +00001023 for var in vars:
1024 args.append("(%s)%s=%s" % (var.GetTypeName(),
1025 var.GetName(),
Greg Claytonfe42ac42011-08-03 22:57:10 +00001026 var.GetValue()))
Johnny Chen3cd1e552011-05-25 19:06:18 +00001027 if frame.GetFunction():
Johnny Chen52b0ffd92011-05-13 00:44:49 +00001028 name = frame.GetFunction().GetName()
Johnny Chen3cd1e552011-05-25 19:06:18 +00001029 elif frame.GetSymbol():
Johnny Chen52b0ffd92011-05-13 00:44:49 +00001030 name = frame.GetSymbol().GetName()
1031 else:
1032 name = ""
Johnny Chen0d4f6dd2011-06-16 22:07:48 +00001033 if showFuncName:
1034 return "%s(%s)" % (name, ", ".join(args))
1035 else:
1036 return "(%s)" % (", ".join(args))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001037
1038
1039def print_registers(frame, string_buffer=False):
Johnny Chen2158b972011-05-08 18:55:37 +00001040 """Prints all the register sets of the frame."""
Johnny Chenb21c52e2011-05-08 17:25:27 +00001041
Zachary Turner814236d2015-10-21 17:48:52 +00001042 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chenb21c52e2011-05-08 17:25:27 +00001043
Zachary Turnerff890da2015-10-19 23:45:41 +00001044 print("Register sets for " + str(frame), file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +00001045
Kate Stoneb9c1b512016-09-06 20:57:50 +00001046 registerSet = frame.GetRegisters() # Return type of SBValueList.
1047 print("Frame registers (size of register set = %d):" %
1048 registerSet.GetSize(), file=output)
Johnny Chen64ff7e62011-05-10 19:21:13 +00001049 for value in registerSet:
Zachary Turner35d017f2015-10-23 17:04:29 +00001050 #print(value, file=output)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001051 print("%s (number of children = %d):" %
1052 (value.GetName(), value.GetNumChildren()), file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +00001053 for child in value:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001054 print(
1055 "Name: %s, Value: %s" %
1056 (child.GetName(),
1057 child.GetValue()),
1058 file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +00001059
1060 if string_buffer:
1061 return output.getvalue()
Johnny Chen64ff7e62011-05-10 19:21:13 +00001062
Kate Stoneb9c1b512016-09-06 20:57:50 +00001063
Johnny Chen64ff7e62011-05-10 19:21:13 +00001064def get_registers(frame, kind):
1065 """Returns the registers given the frame and the kind of registers desired.
1066
1067 Returns None if there's no such kind.
1068 """
Kate Stoneb9c1b512016-09-06 20:57:50 +00001069 registerSet = frame.GetRegisters() # Return type of SBValueList.
Johnny Chen64ff7e62011-05-10 19:21:13 +00001070 for value in registerSet:
1071 if kind.lower() in value.GetName().lower():
1072 return value
1073
1074 return None
1075
Kate Stoneb9c1b512016-09-06 20:57:50 +00001076
Johnny Chen64ff7e62011-05-10 19:21:13 +00001077def get_GPRs(frame):
1078 """Returns the general purpose registers of the frame as an SBValue.
1079
Johnny Chene9e86892011-05-10 23:01:44 +00001080 The returned SBValue object is iterable. An example:
1081 ...
1082 from lldbutil import get_GPRs
1083 regs = get_GPRs(frame)
1084 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +00001085 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +00001086 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +00001087 """
1088 return get_registers(frame, "general purpose")
1089
Kate Stoneb9c1b512016-09-06 20:57:50 +00001090
Johnny Chen64ff7e62011-05-10 19:21:13 +00001091def get_FPRs(frame):
1092 """Returns the floating point registers of the frame as an SBValue.
1093
Johnny Chene9e86892011-05-10 23:01:44 +00001094 The returned SBValue object is iterable. An example:
1095 ...
1096 from lldbutil import get_FPRs
1097 regs = get_FPRs(frame)
1098 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +00001099 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +00001100 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +00001101 """
1102 return get_registers(frame, "floating point")
1103
Kate Stoneb9c1b512016-09-06 20:57:50 +00001104
Johnny Chen64ff7e62011-05-10 19:21:13 +00001105def get_ESRs(frame):
1106 """Returns the exception state registers of the frame as an SBValue.
1107
Johnny Chene9e86892011-05-10 23:01:44 +00001108 The returned SBValue object is iterable. An example:
1109 ...
1110 from lldbutil import get_ESRs
1111 regs = get_ESRs(frame)
1112 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +00001113 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +00001114 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +00001115 """
1116 return get_registers(frame, "exception state")
Johnny Chen989b7ef2011-07-22 00:47:58 +00001117
Johnny Chenefee1cd2011-07-22 00:51:54 +00001118# ======================================
1119# Utility classes/functions for SBValues
1120# ======================================
Johnny Chen989b7ef2011-07-22 00:47:58 +00001121
Kate Stoneb9c1b512016-09-06 20:57:50 +00001122
Johnny Chen989b7ef2011-07-22 00:47:58 +00001123class BasicFormatter(object):
Johnny Chen36d7d912011-07-22 22:01:35 +00001124 """The basic formatter inspects the value object and prints the value."""
Kate Stoneb9c1b512016-09-06 20:57:50 +00001125
Johnny Chen989b7ef2011-07-22 00:47:58 +00001126 def format(self, value, buffer=None, indent=0):
1127 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +00001128 output = SixStringIO()
Johnny Chen989b7ef2011-07-22 00:47:58 +00001129 else:
1130 output = buffer
Johnny Chen36d7d912011-07-22 22:01:35 +00001131 # If there is a summary, it suffices.
1132 val = value.GetSummary()
1133 # Otherwise, get the value.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001134 if val is None:
Johnny Chen36d7d912011-07-22 22:01:35 +00001135 val = value.GetValue()
Kate Stoneb9c1b512016-09-06 20:57:50 +00001136 if val is None and value.GetNumChildren() > 0:
Johnny Chen36d7d912011-07-22 22:01:35 +00001137 val = "%s (location)" % value.GetLocation()
Zachary Turnerff890da2015-10-19 23:45:41 +00001138 print("{indentation}({type}) {name} = {value}".format(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001139 indentation=' ' * indent,
1140 type=value.GetTypeName(),
1141 name=value.GetName(),
1142 value=val), file=output)
Johnny Chen989b7ef2011-07-22 00:47:58 +00001143 return output.getvalue()
1144
Kate Stoneb9c1b512016-09-06 20:57:50 +00001145
Johnny Chen989b7ef2011-07-22 00:47:58 +00001146class ChildVisitingFormatter(BasicFormatter):
Johnny Chen36d7d912011-07-22 22:01:35 +00001147 """The child visiting formatter prints the value and its immediate children.
1148
1149 The constructor takes a keyword arg: indent_child, which defaults to 2.
1150 """
Kate Stoneb9c1b512016-09-06 20:57:50 +00001151
Johnny Chen36d7d912011-07-22 22:01:35 +00001152 def __init__(self, indent_child=2):
1153 """Default indentation of 2 SPC's for the children."""
1154 self.cindent = indent_child
Kate Stoneb9c1b512016-09-06 20:57:50 +00001155
Johnny Chen989b7ef2011-07-22 00:47:58 +00001156 def format(self, value, buffer=None):
1157 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +00001158 output = SixStringIO()
Johnny Chen989b7ef2011-07-22 00:47:58 +00001159 else:
1160 output = buffer
1161
1162 BasicFormatter.format(self, value, buffer=output)
1163 for child in value:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001164 BasicFormatter.format(
1165 self, child, buffer=output, indent=self.cindent)
Johnny Chen36d7d912011-07-22 22:01:35 +00001166
1167 return output.getvalue()
1168
Kate Stoneb9c1b512016-09-06 20:57:50 +00001169
Johnny Chen36d7d912011-07-22 22:01:35 +00001170class RecursiveDecentFormatter(BasicFormatter):
1171 """The recursive decent formatter prints the value and the decendents.
1172
1173 The constructor takes two keyword args: indent_level, which defaults to 0,
1174 and indent_child, which defaults to 2. The current indentation level is
1175 determined by indent_level, while the immediate children has an additional
Kate Stoneb9c1b512016-09-06 20:57:50 +00001176 indentation by inden_child.
Johnny Chen36d7d912011-07-22 22:01:35 +00001177 """
Kate Stoneb9c1b512016-09-06 20:57:50 +00001178
Johnny Chen36d7d912011-07-22 22:01:35 +00001179 def __init__(self, indent_level=0, indent_child=2):
1180 self.lindent = indent_level
1181 self.cindent = indent_child
Kate Stoneb9c1b512016-09-06 20:57:50 +00001182
Johnny Chen36d7d912011-07-22 22:01:35 +00001183 def format(self, value, buffer=None):
1184 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +00001185 output = SixStringIO()
Johnny Chen36d7d912011-07-22 22:01:35 +00001186 else:
1187 output = buffer
1188
1189 BasicFormatter.format(self, value, buffer=output, indent=self.lindent)
1190 new_indent = self.lindent + self.cindent
1191 for child in value:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001192 if child.GetSummary() is not None:
1193 BasicFormatter.format(
1194 self, child, buffer=output, indent=new_indent)
Johnny Chen36d7d912011-07-22 22:01:35 +00001195 else:
1196 if child.GetNumChildren() > 0:
1197 rdf = RecursiveDecentFormatter(indent_level=new_indent)
1198 rdf.format(child, buffer=output)
1199 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001200 BasicFormatter.format(
1201 self, child, buffer=output, indent=new_indent)
Johnny Chen989b7ef2011-07-22 00:47:58 +00001202
1203 return output.getvalue()
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001204
1205# ===========================================================
1206# Utility functions for path manipulation on remote platforms
1207# ===========================================================
1208
Kate Stoneb9c1b512016-09-06 20:57:50 +00001209
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001210def join_remote_paths(*paths):
1211 # TODO: update with actual platform name for remote windows once it exists
1212 if lldb.remote_platform.GetName() == 'remote-windows':
1213 return os.path.join(*paths).replace(os.path.sep, '\\')
1214 return os.path.join(*paths).replace(os.path.sep, '/')
1215
Kate Stoneb9c1b512016-09-06 20:57:50 +00001216
Chaoren Lin5d76b1b2015-06-06 00:25:50 +00001217def append_to_process_working_directory(*paths):
1218 remote = lldb.remote_platform
1219 if remote:
1220 return join_remote_paths(remote.GetWorkingDirectory(), *paths)
1221 return os.path.join(os.getcwd(), *paths)
Chaoren Linf59d05092015-06-02 16:46:28 +00001222
1223# ==================================================
1224# Utility functions to get the correct signal number
1225# ==================================================
1226
1227import signal
1228
Kate Stoneb9c1b512016-09-06 20:57:50 +00001229
Chaoren Linf59d05092015-06-02 16:46:28 +00001230def get_signal_number(signal_name):
1231 platform = lldb.remote_platform
Chaoren Lin98d0a4b2015-07-14 01:09:28 +00001232 if platform and platform.IsValid():
1233 signals = platform.GetUnixSignals()
1234 if signals.IsValid():
Chaoren Lin264e5422015-06-02 18:31:57 +00001235 signal_number = signals.GetSignalNumberFromName(signal_name)
1236 if signal_number > 0:
1237 return signal_number
Chaoren Lin98d0a4b2015-07-14 01:09:28 +00001238 # No remote platform; fall back to using local python signals.
Chaoren Linf59d05092015-06-02 16:46:28 +00001239 return getattr(signal, signal_name)
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001240
Kate Stoneb9c1b512016-09-06 20:57:50 +00001241
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001242class PrintableRegex(object):
Kate Stoneb9c1b512016-09-06 20:57:50 +00001243
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001244 def __init__(self, text):
1245 self.regex = re.compile(text)
1246 self.text = text
Kate Stoneb9c1b512016-09-06 20:57:50 +00001247
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001248 def match(self, str):
1249 return self.regex.match(str)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001250
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001251 def __str__(self):
1252 return "%s" % (self.text)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001253
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001254 def __repr__(self):
1255 return "re.compile(%s) -> %s" % (self.text, self.regex)
1256
Kate Stoneb9c1b512016-09-06 20:57:50 +00001257
Enrico Granataef4fa442015-12-04 19:50:05 +00001258def skip_if_callable(test, mycallable, reason):
1259 if six.callable(mycallable):
1260 if mycallable(test):
1261 test.skipTest(reason)
1262 return True
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001263 return False
1264
Kate Stoneb9c1b512016-09-06 20:57:50 +00001265
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001266def skip_if_library_missing(test, target, library):
1267 def find_library(target, library):
1268 for module in target.modules:
1269 filename = module.file.GetFilename()
1270 if isinstance(library, str):
1271 if library == filename:
1272 return False
1273 elif hasattr(library, 'match'):
1274 if library.match(filename):
1275 return False
1276 return True
Kate Stoneb9c1b512016-09-06 20:57:50 +00001277
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001278 def find_library_callable(test):
1279 return find_library(target, library)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001280 return skip_if_callable(
1281 test,
1282 find_library_callable,
1283 "could not find library matching '%s' in target %s" %
1284 (library,
1285 target))
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001286
Kate Stoneb9c1b512016-09-06 20:57:50 +00001287
1288def wait_for_file_on_target(testcase, file_path, max_attempts=6):
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001289 for i in range(max_attempts):
1290 err, retcode, msg = testcase.run_platform_command("ls %s" % file_path)
1291 if err.Success() and retcode == 0:
1292 break
1293 if i < max_attempts:
1294 # Exponential backoff!
Todd Fiala464f7df2016-04-08 18:06:11 +00001295 import time
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001296 time.sleep(pow(2, i) * 0.25)
1297 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001298 testcase.fail(
1299 "File %s not found even after %d attempts." %
1300 (file_path, max_attempts))
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001301
1302 err, retcode, data = testcase.run_platform_command("cat %s" % (file_path))
1303
Kate Stoneb9c1b512016-09-06 20:57:50 +00001304 testcase.assertTrue(
1305 err.Success() and retcode == 0, "Failed to read file %s: %s, retcode: %d" %
1306 (file_path, err.GetCString(), retcode))
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001307 return data