blob: 58a1ead1ea0bdbd0ed4d89d906805635ddd09513 [file] [log] [blame]
Johnny Chen30ee4ef2010-09-08 22:54:46 +00001"""
Johnny Chen7ea9aee2010-10-07 21:38:28 +00002This LLDB module contains miscellaneous utilities.
Johnny Chenb411b982011-05-13 21:55:30 +00003Some of the test suite takes advantage of the utility functions defined here.
4They can also be useful for general purpose lldb scripting.
Johnny Chen30ee4ef2010-09-08 22:54:46 +00005"""
6
Zachary Turnerff890da2015-10-19 23:45:41 +00007from __future__ import print_function
Zachary Turnerc1b7cd72015-11-05 19:22:28 +00008from __future__ import absolute_import
Zachary Turnerff890da2015-10-19 23:45:41 +00009
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000010# System modules
11import collections
12import os
Enrico Granata0b5a6e32015-09-18 20:12:52 +000013import re
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000014import sys
Pavel Labatha95e0ef2016-04-06 08:55:31 +000015import time
Johnny Chen30ee4ef2010-09-08 22:54:46 +000016
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000017# Third-party modules
Zachary Turner814236d2015-10-21 17:48:52 +000018from six import StringIO as SixStringIO
Zachary Turnercd236b82015-10-26 18:48:24 +000019import six
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000020
21# LLDB modules
22import lldb
23
Zachary Turner814236d2015-10-21 17:48:52 +000024
Johnny Chen6424b7d2011-04-26 23:07:40 +000025# ===================================================
26# Utilities for locating/checking executable programs
27# ===================================================
Johnny Chen4fdcebd2011-04-26 22:53:38 +000028
Johnny Chenac77f3b2011-03-23 20:28:59 +000029def is_exe(fpath):
Johnny Chen35ec6742011-04-26 23:10:15 +000030 """Returns True if fpath is an executable."""
Johnny Chenac77f3b2011-03-23 20:28:59 +000031 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
32
Kate Stoneb9c1b512016-09-06 20:57:50 +000033
Johnny Chenac77f3b2011-03-23 20:28:59 +000034def which(program):
Johnny Chen35ec6742011-04-26 23:10:15 +000035 """Returns the full path to a program; None otherwise."""
Johnny Chenac77f3b2011-03-23 20:28:59 +000036 fpath, fname = os.path.split(program)
37 if fpath:
38 if is_exe(program):
39 return program
40 else:
41 for path in os.environ["PATH"].split(os.pathsep):
42 exe_file = os.path.join(path, program)
43 if is_exe(exe_file):
44 return exe_file
45 return None
46
Johnny Chened401982011-03-03 19:14:00 +000047# ===================================================
48# Disassembly for an SBFunction or an SBSymbol object
49# ===================================================
50
Kate Stoneb9c1b512016-09-06 20:57:50 +000051
Johnny Chened401982011-03-03 19:14:00 +000052def disassemble(target, function_or_symbol):
53 """Disassemble the function or symbol given a target.
54
55 It returns the disassembly content in a string object.
56 """
Zachary Turner814236d2015-10-21 17:48:52 +000057 buf = SixStringIO()
Johnny Chened401982011-03-03 19:14:00 +000058 insts = function_or_symbol.GetInstructions(target)
Johnny Chene69c7482011-04-28 22:57:01 +000059 for i in insts:
Zachary Turnerff890da2015-10-19 23:45:41 +000060 print(i, file=buf)
Johnny Chened401982011-03-03 19:14:00 +000061 return buf.getvalue()
62
Johnny Chen43766d62011-03-02 01:36:45 +000063# ==========================================================
64# Integer (byte size 1, 2, 4, and 8) to bytearray conversion
65# ==========================================================
66
Kate Stoneb9c1b512016-09-06 20:57:50 +000067
Johnny Chen43766d62011-03-02 01:36:45 +000068def int_to_bytearray(val, bytesize):
69 """Utility function to convert an integer into a bytearray.
70
Johnny Chen43e587c2011-03-02 20:54:22 +000071 It returns the bytearray in the little endian format. It is easy to get the
72 big endian format, just do ba.reverse() on the returned object.
Johnny Chen43766d62011-03-02 01:36:45 +000073 """
Johnny Chen90bb9052011-03-30 17:54:35 +000074 import struct
Johnny Chen43766d62011-03-02 01:36:45 +000075
76 if bytesize == 1:
77 return bytearray([val])
78
79 # Little endian followed by a format character.
80 template = "<%c"
81 if bytesize == 2:
82 fmt = template % 'h'
83 elif bytesize == 4:
84 fmt = template % 'i'
85 elif bytesize == 4:
86 fmt = template % 'q'
87 else:
88 return None
89
Johnny Chen90bb9052011-03-30 17:54:35 +000090 packed = struct.pack(fmt, val)
Zachary Turner44073962016-01-25 23:21:18 +000091 return bytearray(packed)
Johnny Chen43766d62011-03-02 01:36:45 +000092
Kate Stoneb9c1b512016-09-06 20:57:50 +000093
Johnny Chen43766d62011-03-02 01:36:45 +000094def bytearray_to_int(bytes, bytesize):
95 """Utility function to convert a bytearray into an integer.
96
Johnny Chen43e587c2011-03-02 20:54:22 +000097 It interprets the bytearray in the little endian format. For a big endian
98 bytearray, just do ba.reverse() on the object before passing it in.
Johnny Chen43766d62011-03-02 01:36:45 +000099 """
Johnny Chen90bb9052011-03-30 17:54:35 +0000100 import struct
Johnny Chen43766d62011-03-02 01:36:45 +0000101
102 if bytesize == 1:
Filipe Cabecinhas5d261b02012-07-06 16:20:13 +0000103 return bytes[0]
Johnny Chen43766d62011-03-02 01:36:45 +0000104
105 # Little endian followed by a format character.
106 template = "<%c"
107 if bytesize == 2:
108 fmt = template % 'h'
109 elif bytesize == 4:
110 fmt = template % 'i'
111 elif bytesize == 4:
112 fmt = template % 'q'
113 else:
114 return None
115
Zachary Turner44073962016-01-25 23:21:18 +0000116 unpacked = struct.unpack_from(fmt, bytes)
Johnny Chen43766d62011-03-02 01:36:45 +0000117 return unpacked[0]
118
119
Johnny Chen90256cd2011-04-23 00:13:34 +0000120# ==============================================================
121# Get the description of an lldb object or None if not available
122# ==============================================================
Johnny Chenfc87e2d2011-04-25 20:23:05 +0000123def get_description(obj, option=None):
124 """Calls lldb_obj.GetDescription() and returns a string, or None.
125
Johnny Chen01a67862011-10-14 00:42:25 +0000126 For SBTarget, SBBreakpointLocation, and SBWatchpoint lldb objects, an extra
127 option can be passed in to describe the detailed level of description
128 desired:
Johnny Chenfc87e2d2011-04-25 20:23:05 +0000129 o lldb.eDescriptionLevelBrief
130 o lldb.eDescriptionLevelFull
131 o lldb.eDescriptionLevelVerbose
132 """
133 method = getattr(obj, 'GetDescription')
Johnny Chen90256cd2011-04-23 00:13:34 +0000134 if not method:
135 return None
Johnny Chen01a67862011-10-14 00:42:25 +0000136 tuple = (lldb.SBTarget, lldb.SBBreakpointLocation, lldb.SBWatchpoint)
Johnny Chen469683e2011-09-27 21:27:19 +0000137 if isinstance(obj, tuple):
Johnny Chenfc87e2d2011-04-25 20:23:05 +0000138 if option is None:
139 option = lldb.eDescriptionLevelBrief
140
Johnny Chen90256cd2011-04-23 00:13:34 +0000141 stream = lldb.SBStream()
142 if option is None:
143 success = method(stream)
144 else:
145 success = method(stream, option)
146 if not success:
147 return None
148 return stream.GetData()
Kate Stoneb9c1b512016-09-06 20:57:50 +0000149
Johnny Chen90256cd2011-04-23 00:13:34 +0000150
Johnny Chenf4f70bb2010-10-22 21:31:03 +0000151# =================================================
152# Convert some enum value to its string counterpart
153# =================================================
Johnny Chen28ae2942010-10-07 22:15:58 +0000154
Johnny Chende90f1d2011-04-27 17:43:07 +0000155def state_type_to_str(enum):
Johnny Chen28ae2942010-10-07 22:15:58 +0000156 """Returns the stateType string given an enum."""
157 if enum == lldb.eStateInvalid:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000158 return "invalid"
Johnny Chen28ae2942010-10-07 22:15:58 +0000159 elif enum == lldb.eStateUnloaded:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000160 return "unloaded"
Johnny Chen930e3ad2011-03-05 01:20:11 +0000161 elif enum == lldb.eStateConnected:
162 return "connected"
Johnny Chen28ae2942010-10-07 22:15:58 +0000163 elif enum == lldb.eStateAttaching:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000164 return "attaching"
Johnny Chen28ae2942010-10-07 22:15:58 +0000165 elif enum == lldb.eStateLaunching:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000166 return "launching"
Johnny Chen28ae2942010-10-07 22:15:58 +0000167 elif enum == lldb.eStateStopped:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000168 return "stopped"
Johnny Chen28ae2942010-10-07 22:15:58 +0000169 elif enum == lldb.eStateRunning:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000170 return "running"
Johnny Chen28ae2942010-10-07 22:15:58 +0000171 elif enum == lldb.eStateStepping:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000172 return "stepping"
Johnny Chen28ae2942010-10-07 22:15:58 +0000173 elif enum == lldb.eStateCrashed:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000174 return "crashed"
Johnny Chen28ae2942010-10-07 22:15:58 +0000175 elif enum == lldb.eStateDetached:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000176 return "detached"
Johnny Chen28ae2942010-10-07 22:15:58 +0000177 elif enum == lldb.eStateExited:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000178 return "exited"
Johnny Chen28ae2942010-10-07 22:15:58 +0000179 elif enum == lldb.eStateSuspended:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000180 return "suspended"
Johnny Chen28ae2942010-10-07 22:15:58 +0000181 else:
Johnny Chen930e3ad2011-03-05 01:20:11 +0000182 raise Exception("Unknown StateType enum")
Johnny Chen28ae2942010-10-07 22:15:58 +0000183
Kate Stoneb9c1b512016-09-06 20:57:50 +0000184
Johnny Chende90f1d2011-04-27 17:43:07 +0000185def stop_reason_to_str(enum):
Johnny Chen28ae2942010-10-07 22:15:58 +0000186 """Returns the stopReason string given an enum."""
187 if enum == lldb.eStopReasonInvalid:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000188 return "invalid"
Johnny Chen28ae2942010-10-07 22:15:58 +0000189 elif enum == lldb.eStopReasonNone:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000190 return "none"
Johnny Chen28ae2942010-10-07 22:15:58 +0000191 elif enum == lldb.eStopReasonTrace:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000192 return "trace"
Johnny Chen28ae2942010-10-07 22:15:58 +0000193 elif enum == lldb.eStopReasonBreakpoint:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000194 return "breakpoint"
Johnny Chen28ae2942010-10-07 22:15:58 +0000195 elif enum == lldb.eStopReasonWatchpoint:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000196 return "watchpoint"
Jim Ingham6cc0d2f2014-04-03 01:25:28 +0000197 elif enum == lldb.eStopReasonExec:
198 return "exec"
Johnny Chen28ae2942010-10-07 22:15:58 +0000199 elif enum == lldb.eStopReasonSignal:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000200 return "signal"
Johnny Chen28ae2942010-10-07 22:15:58 +0000201 elif enum == lldb.eStopReasonException:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000202 return "exception"
Johnny Chen28ae2942010-10-07 22:15:58 +0000203 elif enum == lldb.eStopReasonPlanComplete:
Johnny Chen8b6b1892010-10-18 15:46:54 +0000204 return "plancomplete"
Daniel Maleab3d41a22013-07-09 00:08:01 +0000205 elif enum == lldb.eStopReasonThreadExiting:
206 return "threadexiting"
Johnny Chen28ae2942010-10-07 22:15:58 +0000207 else:
Johnny Chen930e3ad2011-03-05 01:20:11 +0000208 raise Exception("Unknown StopReason enum")
Johnny Chen28ae2942010-10-07 22:15:58 +0000209
Kate Stoneb9c1b512016-09-06 20:57:50 +0000210
Johnny Chena32a13d2011-09-28 00:51:00 +0000211def symbol_type_to_str(enum):
212 """Returns the symbolType string given an enum."""
213 if enum == lldb.eSymbolTypeInvalid:
214 return "invalid"
215 elif enum == lldb.eSymbolTypeAbsolute:
216 return "absolute"
Johnny Chena32a13d2011-09-28 00:51:00 +0000217 elif enum == lldb.eSymbolTypeCode:
218 return "code"
219 elif enum == lldb.eSymbolTypeData:
220 return "data"
221 elif enum == lldb.eSymbolTypeTrampoline:
222 return "trampoline"
223 elif enum == lldb.eSymbolTypeRuntime:
224 return "runtime"
225 elif enum == lldb.eSymbolTypeException:
226 return "exception"
227 elif enum == lldb.eSymbolTypeSourceFile:
228 return "sourcefile"
229 elif enum == lldb.eSymbolTypeHeaderFile:
230 return "headerfile"
231 elif enum == lldb.eSymbolTypeObjectFile:
232 return "objectfile"
233 elif enum == lldb.eSymbolTypeCommonBlock:
234 return "commonblock"
235 elif enum == lldb.eSymbolTypeBlock:
236 return "block"
237 elif enum == lldb.eSymbolTypeLocal:
238 return "local"
239 elif enum == lldb.eSymbolTypeParam:
240 return "param"
241 elif enum == lldb.eSymbolTypeVariable:
242 return "variable"
243 elif enum == lldb.eSymbolTypeVariableType:
244 return "variabletype"
245 elif enum == lldb.eSymbolTypeLineEntry:
246 return "lineentry"
247 elif enum == lldb.eSymbolTypeLineHeader:
248 return "lineheader"
249 elif enum == lldb.eSymbolTypeScopeBegin:
250 return "scopebegin"
251 elif enum == lldb.eSymbolTypeScopeEnd:
252 return "scopeend"
253 elif enum == lldb.eSymbolTypeAdditional:
254 return "additional"
255 elif enum == lldb.eSymbolTypeCompiler:
256 return "compiler"
257 elif enum == lldb.eSymbolTypeInstrumentation:
258 return "instrumentation"
259 elif enum == lldb.eSymbolTypeUndefined:
260 return "undefined"
261
Kate Stoneb9c1b512016-09-06 20:57:50 +0000262
Johnny Chende90f1d2011-04-27 17:43:07 +0000263def value_type_to_str(enum):
Johnny Chen87bb5892010-11-03 21:37:58 +0000264 """Returns the valueType string given an enum."""
265 if enum == lldb.eValueTypeInvalid:
266 return "invalid"
267 elif enum == lldb.eValueTypeVariableGlobal:
268 return "global_variable"
269 elif enum == lldb.eValueTypeVariableStatic:
270 return "static_variable"
271 elif enum == lldb.eValueTypeVariableArgument:
272 return "argument_variable"
273 elif enum == lldb.eValueTypeVariableLocal:
274 return "local_variable"
275 elif enum == lldb.eValueTypeRegister:
276 return "register"
277 elif enum == lldb.eValueTypeRegisterSet:
278 return "register_set"
279 elif enum == lldb.eValueTypeConstResult:
280 return "constant_result"
281 else:
Johnny Chen930e3ad2011-03-05 01:20:11 +0000282 raise Exception("Unknown ValueType enum")
Johnny Chen87bb5892010-11-03 21:37:58 +0000283
Johnny Chen28ae2942010-10-07 22:15:58 +0000284
Johnny Chenf4f70bb2010-10-22 21:31:03 +0000285# ==================================================
Daniel Maleab3d41a22013-07-09 00:08:01 +0000286# Get stopped threads due to each stop reason.
287# ==================================================
288
289def sort_stopped_threads(process,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000290 breakpoint_threads=None,
291 crashed_threads=None,
292 watchpoint_threads=None,
293 signal_threads=None,
294 exiting_threads=None,
295 other_threads=None):
Daniel Maleab3d41a22013-07-09 00:08:01 +0000296 """ Fills array *_threads with threads stopped for the corresponding stop
297 reason.
298 """
299 for lst in [breakpoint_threads,
300 watchpoint_threads,
301 signal_threads,
302 exiting_threads,
303 other_threads]:
304 if lst is not None:
305 lst[:] = []
306
307 for thread in process:
308 dispatched = False
309 for (reason, list) in [(lldb.eStopReasonBreakpoint, breakpoint_threads),
310 (lldb.eStopReasonException, crashed_threads),
311 (lldb.eStopReasonWatchpoint, watchpoint_threads),
312 (lldb.eStopReasonSignal, signal_threads),
313 (lldb.eStopReasonThreadExiting, exiting_threads),
314 (None, other_threads)]:
315 if not dispatched and list is not None:
316 if thread.GetStopReason() == reason or reason is None:
317 list.append(thread)
318 dispatched = True
319
320# ==================================================
Jim Ingham63dfc722012-09-22 00:05:11 +0000321# Utility functions for setting breakpoints
322# ==================================================
323
Kate Stoneb9c1b512016-09-06 20:57:50 +0000324
325def run_break_set_by_file_and_line(
326 test,
327 file_name,
328 line_number,
329 extra_options=None,
330 num_expected_locations=1,
331 loc_exact=False,
332 module_name=None):
333 """Set a breakpoint by file and line, returning the breakpoint number.
Jim Ingham63dfc722012-09-22 00:05:11 +0000334
335 If extra_options is not None, then we append it to the breakpoint set command.
336
337 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.
338
339 If loc_exact is true, we check that there is one location, and that location must be at the input file and line number."""
340
Kate Stoneb9c1b512016-09-06 20:57:50 +0000341 if file_name is None:
342 command = 'breakpoint set -l %d' % (line_number)
Jim Ingham63dfc722012-09-22 00:05:11 +0000343 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000344 command = 'breakpoint set -f "%s" -l %d' % (file_name, line_number)
Jim Ingham63dfc722012-09-22 00:05:11 +0000345
Greg Claytonc1b2ccf2013-01-08 00:01:36 +0000346 if module_name:
347 command += " --shlib '%s'" % (module_name)
348
Jim Ingham63dfc722012-09-22 00:05:11 +0000349 if extra_options:
350 command += " " + extra_options
351
Kate Stoneb9c1b512016-09-06 20:57:50 +0000352 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000353
354 if num_expected_locations == 1 and loc_exact:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000355 check_breakpoint_result(
356 test,
357 break_results,
358 num_locations=num_expected_locations,
359 file_name=file_name,
360 line_number=line_number,
361 module_name=module_name)
Jim Ingham63dfc722012-09-22 00:05:11 +0000362 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000363 check_breakpoint_result(
364 test,
365 break_results,
366 num_locations=num_expected_locations)
Jim Ingham63dfc722012-09-22 00:05:11 +0000367
Kate Stoneb9c1b512016-09-06 20:57:50 +0000368 return get_bpno_from_match(break_results)
Jim Ingham63dfc722012-09-22 00:05:11 +0000369
Kate Stoneb9c1b512016-09-06 20:57:50 +0000370
371def run_break_set_by_symbol(
372 test,
373 symbol,
374 extra_options=None,
375 num_expected_locations=-1,
376 sym_exact=False,
377 module_name=None):
Jim Ingham63dfc722012-09-22 00:05:11 +0000378 """Set a breakpoint by symbol name. Common options are the same as run_break_set_by_file_and_line.
379
380 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 +0000381 command = 'breakpoint set -n "%s"' % (symbol)
Greg Claytonc1b2ccf2013-01-08 00:01:36 +0000382
383 if module_name:
384 command += " --shlib '%s'" % (module_name)
385
Jim Ingham63dfc722012-09-22 00:05:11 +0000386 if extra_options:
387 command += " " + extra_options
388
Kate Stoneb9c1b512016-09-06 20:57:50 +0000389 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000390
391 if num_expected_locations == 1 and sym_exact:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000392 check_breakpoint_result(
393 test,
394 break_results,
395 num_locations=num_expected_locations,
396 symbol_name=symbol,
397 module_name=module_name)
Jim Ingham63dfc722012-09-22 00:05:11 +0000398 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000399 check_breakpoint_result(
400 test,
401 break_results,
402 num_locations=num_expected_locations)
Jim Ingham63dfc722012-09-22 00:05:11 +0000403
Kate Stoneb9c1b512016-09-06 20:57:50 +0000404 return get_bpno_from_match(break_results)
Jim Ingham63dfc722012-09-22 00:05:11 +0000405
Kate Stoneb9c1b512016-09-06 20:57:50 +0000406
407def run_break_set_by_selector(
408 test,
409 selector,
410 extra_options=None,
411 num_expected_locations=-1,
412 module_name=None):
Jim Ingham63dfc722012-09-22 00:05:11 +0000413 """Set a breakpoint by selector. Common options are the same as run_break_set_by_file_and_line."""
414
Greg Claytonc1b2ccf2013-01-08 00:01:36 +0000415 command = 'breakpoint set -S "%s"' % (selector)
416
417 if module_name:
418 command += ' --shlib "%s"' % (module_name)
419
Jim Ingham63dfc722012-09-22 00:05:11 +0000420 if extra_options:
421 command += " " + extra_options
422
Kate Stoneb9c1b512016-09-06 20:57:50 +0000423 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000424
425 if num_expected_locations == 1:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000426 check_breakpoint_result(
427 test,
428 break_results,
429 num_locations=num_expected_locations,
430 symbol_name=selector,
431 symbol_match_exact=False,
432 module_name=module_name)
Jim Ingham63dfc722012-09-22 00:05:11 +0000433 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000434 check_breakpoint_result(
435 test,
436 break_results,
437 num_locations=num_expected_locations)
Jim Ingham63dfc722012-09-22 00:05:11 +0000438
Kate Stoneb9c1b512016-09-06 20:57:50 +0000439 return get_bpno_from_match(break_results)
Jim Ingham63dfc722012-09-22 00:05:11 +0000440
Kate Stoneb9c1b512016-09-06 20:57:50 +0000441
442def run_break_set_by_regexp(
443 test,
444 regexp,
445 extra_options=None,
446 num_expected_locations=-1):
Jim Ingham63dfc722012-09-22 00:05:11 +0000447 """Set a breakpoint by regular expression match on symbol name. Common options are the same as run_break_set_by_file_and_line."""
448
Kate Stoneb9c1b512016-09-06 20:57:50 +0000449 command = 'breakpoint set -r "%s"' % (regexp)
Jim Ingham63dfc722012-09-22 00:05:11 +0000450 if extra_options:
451 command += " " + extra_options
Jim Ingham63dfc722012-09-22 00:05:11 +0000452
Kate Stoneb9c1b512016-09-06 20:57:50 +0000453 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000454
Kate Stoneb9c1b512016-09-06 20:57:50 +0000455 check_breakpoint_result(
456 test,
457 break_results,
458 num_locations=num_expected_locations)
459
460 return get_bpno_from_match(break_results)
461
462
463def run_break_set_by_source_regexp(
464 test,
465 regexp,
466 extra_options=None,
467 num_expected_locations=-1):
Jim Ingham63dfc722012-09-22 00:05:11 +0000468 """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 +0000469 command = 'breakpoint set -p "%s"' % (regexp)
Jim Ingham63dfc722012-09-22 00:05:11 +0000470 if extra_options:
471 command += " " + extra_options
Jim Ingham63dfc722012-09-22 00:05:11 +0000472
Kate Stoneb9c1b512016-09-06 20:57:50 +0000473 break_results = run_break_set_command(test, command)
Jim Ingham63dfc722012-09-22 00:05:11 +0000474
Kate Stoneb9c1b512016-09-06 20:57:50 +0000475 check_breakpoint_result(
476 test,
477 break_results,
478 num_locations=num_expected_locations)
479
480 return get_bpno_from_match(break_results)
481
482
483def run_break_set_command(test, command):
484 """Run the command passed in - it must be some break set variant - and analyze the result.
Jim Ingham63dfc722012-09-22 00:05:11 +0000485 Returns a dictionary of information gleaned from the command-line results.
486 Will assert if the breakpoint setting fails altogether.
487
488 Dictionary will contain:
489 bpno - breakpoint of the newly created breakpoint, -1 on error.
490 num_locations - number of locations set for the breakpoint.
491
492 If there is only one location, the dictionary MAY contain:
493 file - source file name
494 line_no - source line number
495 symbol - symbol name
496 inline_symbol - inlined symbol name
497 offset - offset from the original symbol
498 module - module
499 address - address at which the breakpoint was set."""
500
Kate Stoneb9c1b512016-09-06 20:57:50 +0000501 patterns = [
502 r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>[0-9]+) locations\.$",
503 r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>no) locations \(pending\)\.",
504 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]+)$",
505 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]+)$"]
506 match_object = test.match(command, patterns)
Jim Ingham63dfc722012-09-22 00:05:11 +0000507 break_results = match_object.groupdict()
Jim Ingham63dfc722012-09-22 00:05:11 +0000508
509 # We always insert the breakpoint number, setting it to -1 if we couldn't find it
510 # Also, make sure it gets stored as an integer.
511 if not 'bpno' in break_results:
512 break_results['bpno'] = -1
513 else:
514 break_results['bpno'] = int(break_results['bpno'])
Kate Stoneb9c1b512016-09-06 20:57:50 +0000515
Jim Ingham63dfc722012-09-22 00:05:11 +0000516 # We always insert the number of locations
517 # If ONE location is set for the breakpoint, then the output doesn't mention locations, but it has to be 1...
518 # We also make sure it is an integer.
519
520 if not 'num_locations' in break_results:
521 num_locations = 1
522 else:
523 num_locations = break_results['num_locations']
524 if num_locations == 'no':
525 num_locations = 0
526 else:
527 num_locations = int(break_results['num_locations'])
528
529 break_results['num_locations'] = num_locations
Kate Stoneb9c1b512016-09-06 20:57:50 +0000530
Jim Ingham63dfc722012-09-22 00:05:11 +0000531 if 'line_no' in break_results:
532 break_results['line_no'] = int(break_results['line_no'])
533
534 return break_results
535
Jim Ingham63dfc722012-09-22 00:05:11 +0000536
Kate Stoneb9c1b512016-09-06 20:57:50 +0000537def get_bpno_from_match(break_results):
538 return int(break_results['bpno'])
539
540
541def check_breakpoint_result(
542 test,
543 break_results,
544 file_name=None,
545 line_number=-1,
546 symbol_name=None,
547 symbol_match_exact=True,
548 module_name=None,
549 offset=-1,
550 num_locations=-1):
Jim Ingham63dfc722012-09-22 00:05:11 +0000551
552 out_num_locations = break_results['num_locations']
553
Jim Ingham63dfc722012-09-22 00:05:11 +0000554 if num_locations == -1:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000555 test.assertTrue(out_num_locations > 0,
556 "Expecting one or more locations, got none.")
Jim Ingham63dfc722012-09-22 00:05:11 +0000557 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000558 test.assertTrue(
559 num_locations == out_num_locations,
560 "Expecting %d locations, got %d." %
561 (num_locations,
562 out_num_locations))
Jim Ingham63dfc722012-09-22 00:05:11 +0000563
564 if file_name:
565 out_file_name = ""
566 if 'file' in break_results:
567 out_file_name = break_results['file']
Kate Stoneb9c1b512016-09-06 20:57:50 +0000568 test.assertTrue(
569 file_name == out_file_name,
570 "Breakpoint file name '%s' doesn't match resultant name '%s'." %
571 (file_name,
572 out_file_name))
Jim Ingham63dfc722012-09-22 00:05:11 +0000573
574 if line_number != -1:
Ilia K055ad9b2015-05-18 13:41:01 +0000575 out_line_number = -1
Jim Ingham63dfc722012-09-22 00:05:11 +0000576 if 'line_no' in break_results:
577 out_line_number = break_results['line_no']
578
Kate Stoneb9c1b512016-09-06 20:57:50 +0000579 test.assertTrue(
580 line_number == out_line_number,
581 "Breakpoint line number %s doesn't match resultant line %s." %
582 (line_number,
583 out_line_number))
Jim Ingham63dfc722012-09-22 00:05:11 +0000584
585 if symbol_name:
586 out_symbol_name = ""
Kate Stoneb9c1b512016-09-06 20:57:50 +0000587 # Look first for the inlined symbol name, otherwise use the symbol
588 # name:
Jim Ingham63dfc722012-09-22 00:05:11 +0000589 if 'inline_symbol' in break_results and break_results['inline_symbol']:
590 out_symbol_name = break_results['inline_symbol']
591 elif 'symbol' in break_results:
592 out_symbol_name = break_results['symbol']
593
594 if symbol_match_exact:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000595 test.assertTrue(
596 symbol_name == out_symbol_name,
597 "Symbol name '%s' doesn't match resultant symbol '%s'." %
598 (symbol_name,
599 out_symbol_name))
Jim Ingham63dfc722012-09-22 00:05:11 +0000600 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000601 test.assertTrue(
602 out_symbol_name.find(symbol_name) != -
603 1,
604 "Symbol name '%s' isn't in resultant symbol '%s'." %
605 (symbol_name,
606 out_symbol_name))
Jim Ingham63dfc722012-09-22 00:05:11 +0000607
608 if module_name:
Ilia K055ad9b2015-05-18 13:41:01 +0000609 out_module_name = None
Jim Ingham63dfc722012-09-22 00:05:11 +0000610 if 'module' in break_results:
611 out_module_name = break_results['module']
Kate Stoneb9c1b512016-09-06 20:57:50 +0000612
613 test.assertTrue(
614 module_name.find(out_module_name) != -
615 1,
616 "Symbol module name '%s' isn't in expected module name '%s'." %
617 (out_module_name,
618 module_name))
Jim Ingham63dfc722012-09-22 00:05:11 +0000619
620# ==================================================
Johnny Chenf4f70bb2010-10-22 21:31:03 +0000621# Utility functions related to Threads and Processes
622# ==================================================
Johnny Chen28ae2942010-10-07 22:15:58 +0000623
Kate Stoneb9c1b512016-09-06 20:57:50 +0000624
Johnny Chend3699082011-04-25 22:04:05 +0000625def get_stopped_threads(process, reason):
Johnny Chen75ec1592011-05-26 21:53:05 +0000626 """Returns the thread(s) with the specified stop reason in a list.
627
628 The list can be empty if no such thread exists.
629 """
Johnny Chend3699082011-04-25 22:04:05 +0000630 threads = []
Johnny Chene69c7482011-04-28 22:57:01 +0000631 for t in process:
Johnny Chend3699082011-04-25 22:04:05 +0000632 if t.GetStopReason() == reason:
633 threads.append(t)
634 return threads
635
Kate Stoneb9c1b512016-09-06 20:57:50 +0000636
Johnny Chend3699082011-04-25 22:04:05 +0000637def get_stopped_thread(process, reason):
638 """A convenience function which returns the first thread with the given stop
639 reason or None.
640
641 Example usages:
642
643 1. Get the stopped thread due to a breakpoint condition
644
645 ...
646 from lldbutil import get_stopped_thread
Johnny Chen5a0bee72011-06-15 22:14:12 +0000647 thread = get_stopped_thread(process, lldb.eStopReasonPlanComplete)
Greg Clayton53c5ddf2013-03-19 17:59:30 +0000648 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition")
Johnny Chend3699082011-04-25 22:04:05 +0000649 ...
650
651 2. Get the thread stopped due to a breakpoint
652
653 ...
654 from lldbutil import get_stopped_thread
Johnny Chen5a0bee72011-06-15 22:14:12 +0000655 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
Greg Clayton53c5ddf2013-03-19 17:59:30 +0000656 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint")
Johnny Chend3699082011-04-25 22:04:05 +0000657 ...
658
659 """
660 threads = get_stopped_threads(process, reason)
661 if len(threads) == 0:
662 return None
663 return threads[0]
664
Kate Stoneb9c1b512016-09-06 20:57:50 +0000665
Zachary Turner1da094a2016-01-22 23:54:41 +0000666def get_threads_stopped_at_breakpoint_id(process, bpid):
Johnny Chend0fef812011-04-25 23:38:13 +0000667 """ For a stopped process returns the thread stopped at the breakpoint passed in bkpt"""
668 stopped_threads = []
669 threads = []
670
Kate Stoneb9c1b512016-09-06 20:57:50 +0000671 stopped_threads = get_stopped_threads(process, lldb.eStopReasonBreakpoint)
Johnny Chend0fef812011-04-25 23:38:13 +0000672
673 if len(stopped_threads) == 0:
674 return threads
Kate Stoneb9c1b512016-09-06 20:57:50 +0000675
Johnny Chend0fef812011-04-25 23:38:13 +0000676 for thread in stopped_threads:
Johnny Chen32391242011-12-22 20:21:46 +0000677 # Make sure we've hit our breakpoint...
Kate Stoneb9c1b512016-09-06 20:57:50 +0000678 break_id = thread.GetStopReasonDataAtIndex(0)
Zachary Turner1da094a2016-01-22 23:54:41 +0000679 if break_id == bpid:
Johnny Chend0fef812011-04-25 23:38:13 +0000680 threads.append(thread)
681
682 return threads
683
Kate Stoneb9c1b512016-09-06 20:57:50 +0000684
685def get_threads_stopped_at_breakpoint(process, bkpt):
Zachary Turner1da094a2016-01-22 23:54:41 +0000686 return get_threads_stopped_at_breakpoint_id(process, bkpt.GetID())
687
Kate Stoneb9c1b512016-09-06 20:57:50 +0000688
689def get_one_thread_stopped_at_breakpoint_id(
690 process, bpid, require_exactly_one=True):
Zachary Turner1da094a2016-01-22 23:54:41 +0000691 threads = get_threads_stopped_at_breakpoint_id(process, bpid)
Zachary Turner783550b2016-01-21 21:07:30 +0000692 if len(threads) == 0:
693 return None
694 if require_exactly_one and len(threads) != 1:
695 return None
696
697 return threads[0]
698
Zachary Turner1da094a2016-01-22 23:54:41 +0000699
Kate Stoneb9c1b512016-09-06 20:57:50 +0000700def get_one_thread_stopped_at_breakpoint(
701 process, bkpt, require_exactly_one=True):
702 return get_one_thread_stopped_at_breakpoint_id(
703 process, bkpt.GetID(), require_exactly_one)
704
705
706def is_thread_crashed(test, thread):
Pavel Labathc4e25c92015-05-29 10:13:03 +0000707 """In the test suite we dereference a null pointer to simulate a crash. The way this is
708 reported depends on the platform."""
709 if test.platformIsDarwin():
Kate Stoneb9c1b512016-09-06 20:57:50 +0000710 return thread.GetStopReason(
711 ) == lldb.eStopReasonException and "EXC_BAD_ACCESS" in thread.GetStopDescription(100)
Pavel Labathc4e25c92015-05-29 10:13:03 +0000712 elif test.getPlatform() == "linux":
Kate Stoneb9c1b512016-09-06 20:57:50 +0000713 return thread.GetStopReason() == lldb.eStopReasonSignal and thread.GetStopReasonDataAtIndex(
714 0) == thread.GetProcess().GetUnixSignals().GetSignalNumberFromName("SIGSEGV")
Pavel Labathc4e25c92015-05-29 10:13:03 +0000715 else:
716 return "invalid address" in thread.GetStopDescription(100)
717
Kate Stoneb9c1b512016-09-06 20:57:50 +0000718
719def get_crashed_threads(test, process):
Pavel Labathc4e25c92015-05-29 10:13:03 +0000720 threads = []
721 if process.GetState() != lldb.eStateStopped:
722 return threads
723 for thread in process:
724 if is_thread_crashed(test, thread):
725 threads.append(thread)
726 return threads
727
Jim Inghama15e7f22017-07-06 02:18:16 +0000728def run_to_source_breakpoint(test, bkpt_pattern, source_spec, launch_info = None, exe_name = "a.out", in_cwd = True):
729 """Start up a target, using exe_name as the executable, and run it to
730 a breakpoint set by source regex bkpt_pattern.
731 If you want to pass in launch arguments or environment variables, you can optionally pass in
732 an SBLaunchInfo. If you do that, remember to set the working directory as well.
733 If your executable isn't called a.out, you can pass that in. And if your executable isn't
734 in the CWD, pass in the absolute path to the executable in exe_name, and set in_cwd to False.
735 If the target isn't valid, the breakpoint isn't found, or hit, the
736 function will cause a testsuite failure.
737 If successful it returns a tuple with the target process and thread that hit the breakpoint."""
738
739 if in_cwd:
740 exe = os.path.join(os.getcwd(), exe_name)
741
742 # Create the target
743 target = test.dbg.CreateTarget(exe)
744 test.assertTrue(target, "Target: %s is not valid."%(exe_name))
745
746 # Set the breakpoints
747 breakpoint = target.BreakpointCreateBySourceRegex(
748 bkpt_pattern, source_spec)
749 test.assertTrue(breakpoint.GetNumLocations() > 0,
750 'No locations found for source breakpoint: "%s"'%(bkpt_pattern))
751
752 # Launch the process, and do not stop at the entry point.
753 if not launch_info:
754 launch_info = lldb.SBLaunchInfo(None)
755 launch_info.SetWorkingDirectory(test.get_process_working_directory())
756
757 error = lldb.SBError()
758 process = target.Launch(launch_info, error)
759
760 test.assertTrue(process, "Could not create a valid process for %s: %s"%(exe_name, error.GetCString()))
761
762 # Frame #0 should be at our breakpoint.
763 threads = get_threads_stopped_at_breakpoint(
764 process, breakpoint)
765
766 test.assertTrue(len(threads) == 1, "Expected 1 thread to stop at breakpoint, %d did."%(len(threads)))
767 thread = threads[0]
768 return (target, process, thread, breakpoint)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000769
770def continue_to_breakpoint(process, bkpt):
Johnny Chend0fef812011-04-25 23:38:13 +0000771 """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None"""
772 process.Continue()
773 if process.GetState() != lldb.eStateStopped:
774 return None
775 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000776 return get_threads_stopped_at_breakpoint(process, bkpt)
777
Johnny Chend0fef812011-04-25 23:38:13 +0000778
Johnny Chena4603162011-03-09 23:45:56 +0000779def get_caller_symbol(thread):
780 """
781 Returns the symbol name for the call site of the leaf function.
782 """
783 depth = thread.GetNumFrames()
784 if depth <= 1:
785 return None
786 caller = thread.GetFrameAtIndex(1).GetSymbol()
787 if caller:
788 return caller.GetName()
789 else:
790 return None
791
792
Johnny Chend0fef812011-04-25 23:38:13 +0000793def get_function_names(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000794 """
795 Returns a sequence of function names from the stack frames of this thread.
796 """
797 def GetFuncName(i):
Johnny Chen4cfd07e2011-06-20 00:26:39 +0000798 return thread.GetFrameAtIndex(i).GetFunctionName()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000799
Zachary Turner744cd5d2015-10-26 16:49:57 +0000800 return list(map(GetFuncName, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000801
802
Johnny Chend0fef812011-04-25 23:38:13 +0000803def get_symbol_names(thread):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000804 """
805 Returns a sequence of symbols for this thread.
806 """
807 def GetSymbol(i):
808 return thread.GetFrameAtIndex(i).GetSymbol().GetName()
809
Zachary Turner744cd5d2015-10-26 16:49:57 +0000810 return list(map(GetSymbol, list(range(thread.GetNumFrames()))))
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000811
812
Johnny Chend0fef812011-04-25 23:38:13 +0000813def get_pc_addresses(thread):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000814 """
815 Returns a sequence of pc addresses for this thread.
816 """
817 def GetPCAddress(i):
818 return thread.GetFrameAtIndex(i).GetPCAddress()
819
Zachary Turner744cd5d2015-10-26 16:49:57 +0000820 return list(map(GetPCAddress, list(range(thread.GetNumFrames()))))
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000821
822
Johnny Chend0fef812011-04-25 23:38:13 +0000823def get_filenames(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000824 """
825 Returns a sequence of file names from the stack frames of this thread.
826 """
827 def GetFilename(i):
Kate Stoneb9c1b512016-09-06 20:57:50 +0000828 return thread.GetFrameAtIndex(
829 i).GetLineEntry().GetFileSpec().GetFilename()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000830
Zachary Turner744cd5d2015-10-26 16:49:57 +0000831 return list(map(GetFilename, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000832
833
Johnny Chend0fef812011-04-25 23:38:13 +0000834def get_line_numbers(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000835 """
836 Returns a sequence of line numbers from the stack frames of this thread.
837 """
838 def GetLineNumber(i):
839 return thread.GetFrameAtIndex(i).GetLineEntry().GetLine()
840
Zachary Turner744cd5d2015-10-26 16:49:57 +0000841 return list(map(GetLineNumber, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000842
843
Johnny Chend0fef812011-04-25 23:38:13 +0000844def get_module_names(thread):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000845 """
846 Returns a sequence of module names from the stack frames of this thread.
847 """
848 def GetModuleName(i):
Kate Stoneb9c1b512016-09-06 20:57:50 +0000849 return thread.GetFrameAtIndex(
850 i).GetModule().GetFileSpec().GetFilename()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000851
Zachary Turner744cd5d2015-10-26 16:49:57 +0000852 return list(map(GetModuleName, list(range(thread.GetNumFrames()))))
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000853
854
Johnny Chend0fef812011-04-25 23:38:13 +0000855def get_stack_frames(thread):
Johnny Chen43a651c2010-09-09 00:55:07 +0000856 """
857 Returns a sequence of stack frames for this thread.
858 """
859 def GetStackFrame(i):
860 return thread.GetFrameAtIndex(i)
861
Zachary Turner744cd5d2015-10-26 16:49:57 +0000862 return list(map(GetStackFrame, list(range(thread.GetNumFrames()))))
Johnny Chen43a651c2010-09-09 00:55:07 +0000863
864
Kate Stoneb9c1b512016-09-06 20:57:50 +0000865def print_stacktrace(thread, string_buffer=False):
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000866 """Prints a simple stack trace of this thread."""
Johnny Chen6c704992010-10-07 18:52:48 +0000867
Zachary Turner814236d2015-10-21 17:48:52 +0000868 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000869 target = thread.GetProcess().GetTarget()
870
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000871 depth = thread.GetNumFrames()
872
Johnny Chend0fef812011-04-25 23:38:13 +0000873 mods = get_module_names(thread)
874 funcs = get_function_names(thread)
875 symbols = get_symbol_names(thread)
876 files = get_filenames(thread)
877 lines = get_line_numbers(thread)
878 addrs = get_pc_addresses(thread)
Johnny Chen6c704992010-10-07 18:52:48 +0000879
Johnny Chen567a0452010-10-25 19:13:52 +0000880 if thread.GetStopReason() != lldb.eStopReasonInvalid:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000881 desc = "stop reason=" + stop_reason_to_str(thread.GetStopReason())
Johnny Chen567a0452010-10-25 19:13:52 +0000882 else:
883 desc = ""
Kate Stoneb9c1b512016-09-06 20:57:50 +0000884 print(
885 "Stack trace for thread id={0:#x} name={1} queue={2} ".format(
886 thread.GetThreadID(),
887 thread.GetName(),
888 thread.GetQueueName()) + desc,
889 file=output)
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000890
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000891 for i in range(depth):
892 frame = thread.GetFrameAtIndex(i)
893 function = frame.GetFunction()
Johnny Chen30ee4ef2010-09-08 22:54:46 +0000894
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000895 load_addr = addrs[i].GetLoadAddress(target)
Johnny Chen3cd1e552011-05-25 19:06:18 +0000896 if not function:
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000897 file_addr = addrs[i].GetFileAddress()
Johnny Chen0d4f6dd2011-06-16 22:07:48 +0000898 start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress()
899 symbol_offset = file_addr - start_addr
Kate Stoneb9c1b512016-09-06 20:57:50 +0000900 print(
901 " frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format(
902 num=i,
903 addr=load_addr,
904 mod=mods[i],
905 symbol=symbols[i],
906 offset=symbol_offset),
907 file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000908 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000909 print(
910 " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format(
911 num=i,
912 addr=load_addr,
913 mod=mods[i],
914 func='%s [inlined]' %
915 funcs[i] if frame.IsInlined() else funcs[i],
916 file=files[i],
917 line=lines[i],
918 args=get_args_as_string(
919 frame,
920 showFuncName=False) if not frame.IsInlined() else '()'),
921 file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000922
923 if string_buffer:
Johnny Chend5d6fac2010-10-15 23:33:18 +0000924 return output.getvalue()
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000925
926
Kate Stoneb9c1b512016-09-06 20:57:50 +0000927def print_stacktraces(process, string_buffer=False):
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000928 """Prints the stack traces of all the threads."""
929
Zachary Turner814236d2015-10-21 17:48:52 +0000930 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000931
Zachary Turnerff890da2015-10-19 23:45:41 +0000932 print("Stack traces for " + str(process), file=output)
Johnny Chen7ea9aee2010-10-07 21:38:28 +0000933
Johnny Chenae9639a2011-05-05 18:50:56 +0000934 for thread in process:
Zachary Turnerff890da2015-10-19 23:45:41 +0000935 print(print_stacktrace(thread, string_buffer=True), file=output)
Johnny Chen6c704992010-10-07 18:52:48 +0000936
937 if string_buffer:
Johnny Chend5d6fac2010-10-15 23:33:18 +0000938 return output.getvalue()
Johnny Chenb21c52e2011-05-08 17:25:27 +0000939
Kate Stoneb9c1b512016-09-06 20:57:50 +0000940
941def expect_state_changes(test, listener, process, states, timeout=5):
Pavel Labath5dcb0252015-09-02 09:12:28 +0000942 """Listens for state changed events on the listener and makes sure they match what we
943 expect. Stop-and-restart events (where GetRestartedFromEvent() returns true) are ignored."""
Pavel Labathe5c98082016-01-06 11:40:06 +0000944
Pavel Labath5dcb0252015-09-02 09:12:28 +0000945 for expected_state in states:
Pavel Labathe5c98082016-01-06 11:40:06 +0000946 def get_next_event():
947 event = lldb.SBEvent()
Kate Stoneb9c1b512016-09-06 20:57:50 +0000948 if not listener.WaitForEventForBroadcasterWithType(
949 timeout,
950 process.GetBroadcaster(),
951 lldb.SBProcess.eBroadcastBitStateChanged,
952 event):
953 test.fail(
954 "Timed out while waiting for a transition to state %s" %
Pavel Labathe5c98082016-01-06 11:40:06 +0000955 lldb.SBDebugger.StateAsCString(expected_state))
956 return event
Pavel Labath5dcb0252015-09-02 09:12:28 +0000957
Pavel Labathe5c98082016-01-06 11:40:06 +0000958 event = get_next_event()
959 while (lldb.SBProcess.GetStateFromEvent(event) == lldb.eStateStopped and
960 lldb.SBProcess.GetRestartedFromEvent(event)):
961 # Ignore restarted event and the subsequent running event.
962 event = get_next_event()
Kate Stoneb9c1b512016-09-06 20:57:50 +0000963 test.assertEqual(
964 lldb.SBProcess.GetStateFromEvent(event),
965 lldb.eStateRunning,
966 "Restarted event followed by a running event")
Pavel Labathe5c98082016-01-06 11:40:06 +0000967 event = get_next_event()
Pavel Labath5dcb0252015-09-02 09:12:28 +0000968
Kate Stoneb9c1b512016-09-06 20:57:50 +0000969 test.assertEqual(
970 lldb.SBProcess.GetStateFromEvent(event),
971 expected_state)
Pavel Labath5dcb0252015-09-02 09:12:28 +0000972
Johnny Chenb21c52e2011-05-08 17:25:27 +0000973# ===================================
974# Utility functions related to Frames
975# ===================================
976
Kate Stoneb9c1b512016-09-06 20:57:50 +0000977
Johnny Chenad7372c2011-05-12 00:32:41 +0000978def get_parent_frame(frame):
979 """
980 Returns the parent frame of the input frame object; None if not available.
981 """
982 thread = frame.GetThread()
983 parent_found = False
984 for f in thread:
985 if parent_found:
986 return f
987 if f.GetFrameID() == frame.GetFrameID():
988 parent_found = True
989
990 # If we reach here, no parent has been found, return None.
991 return None
992
Kate Stoneb9c1b512016-09-06 20:57:50 +0000993
Johnny Chen0d4f6dd2011-06-16 22:07:48 +0000994def get_args_as_string(frame, showFuncName=True):
Johnny Chenad7372c2011-05-12 00:32:41 +0000995 """
996 Returns the args of the input frame object as a string.
997 """
998 # arguments => True
999 # locals => False
1000 # statics => False
1001 # in_scope_only => True
Kate Stoneb9c1b512016-09-06 20:57:50 +00001002 vars = frame.GetVariables(True, False, False, True) # type of SBValueList
1003 args = [] # list of strings
Johnny Chenad7372c2011-05-12 00:32:41 +00001004 for var in vars:
1005 args.append("(%s)%s=%s" % (var.GetTypeName(),
1006 var.GetName(),
Greg Claytonfe42ac42011-08-03 22:57:10 +00001007 var.GetValue()))
Johnny Chen3cd1e552011-05-25 19:06:18 +00001008 if frame.GetFunction():
Johnny Chen52b0ffd92011-05-13 00:44:49 +00001009 name = frame.GetFunction().GetName()
Johnny Chen3cd1e552011-05-25 19:06:18 +00001010 elif frame.GetSymbol():
Johnny Chen52b0ffd92011-05-13 00:44:49 +00001011 name = frame.GetSymbol().GetName()
1012 else:
1013 name = ""
Johnny Chen0d4f6dd2011-06-16 22:07:48 +00001014 if showFuncName:
1015 return "%s(%s)" % (name, ", ".join(args))
1016 else:
1017 return "(%s)" % (", ".join(args))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001018
1019
1020def print_registers(frame, string_buffer=False):
Johnny Chen2158b972011-05-08 18:55:37 +00001021 """Prints all the register sets of the frame."""
Johnny Chenb21c52e2011-05-08 17:25:27 +00001022
Zachary Turner814236d2015-10-21 17:48:52 +00001023 output = SixStringIO() if string_buffer else sys.stdout
Johnny Chenb21c52e2011-05-08 17:25:27 +00001024
Zachary Turnerff890da2015-10-19 23:45:41 +00001025 print("Register sets for " + str(frame), file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +00001026
Kate Stoneb9c1b512016-09-06 20:57:50 +00001027 registerSet = frame.GetRegisters() # Return type of SBValueList.
1028 print("Frame registers (size of register set = %d):" %
1029 registerSet.GetSize(), file=output)
Johnny Chen64ff7e62011-05-10 19:21:13 +00001030 for value in registerSet:
Zachary Turner35d017f2015-10-23 17:04:29 +00001031 #print(value, file=output)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001032 print("%s (number of children = %d):" %
1033 (value.GetName(), value.GetNumChildren()), file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +00001034 for child in value:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001035 print(
1036 "Name: %s, Value: %s" %
1037 (child.GetName(),
1038 child.GetValue()),
1039 file=output)
Johnny Chenb21c52e2011-05-08 17:25:27 +00001040
1041 if string_buffer:
1042 return output.getvalue()
Johnny Chen64ff7e62011-05-10 19:21:13 +00001043
Kate Stoneb9c1b512016-09-06 20:57:50 +00001044
Johnny Chen64ff7e62011-05-10 19:21:13 +00001045def get_registers(frame, kind):
1046 """Returns the registers given the frame and the kind of registers desired.
1047
1048 Returns None if there's no such kind.
1049 """
Kate Stoneb9c1b512016-09-06 20:57:50 +00001050 registerSet = frame.GetRegisters() # Return type of SBValueList.
Johnny Chen64ff7e62011-05-10 19:21:13 +00001051 for value in registerSet:
1052 if kind.lower() in value.GetName().lower():
1053 return value
1054
1055 return None
1056
Kate Stoneb9c1b512016-09-06 20:57:50 +00001057
Johnny Chen64ff7e62011-05-10 19:21:13 +00001058def get_GPRs(frame):
1059 """Returns the general purpose registers of the frame as an SBValue.
1060
Johnny Chene9e86892011-05-10 23:01:44 +00001061 The returned SBValue object is iterable. An example:
1062 ...
1063 from lldbutil import get_GPRs
1064 regs = get_GPRs(frame)
1065 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +00001066 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +00001067 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +00001068 """
1069 return get_registers(frame, "general purpose")
1070
Kate Stoneb9c1b512016-09-06 20:57:50 +00001071
Johnny Chen64ff7e62011-05-10 19:21:13 +00001072def get_FPRs(frame):
1073 """Returns the floating point registers of the frame as an SBValue.
1074
Johnny Chene9e86892011-05-10 23:01:44 +00001075 The returned SBValue object is iterable. An example:
1076 ...
1077 from lldbutil import get_FPRs
1078 regs = get_FPRs(frame)
1079 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +00001080 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +00001081 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +00001082 """
1083 return get_registers(frame, "floating point")
1084
Kate Stoneb9c1b512016-09-06 20:57:50 +00001085
Johnny Chen64ff7e62011-05-10 19:21:13 +00001086def get_ESRs(frame):
1087 """Returns the exception state registers of the frame as an SBValue.
1088
Johnny Chene9e86892011-05-10 23:01:44 +00001089 The returned SBValue object is iterable. An example:
1090 ...
1091 from lldbutil import get_ESRs
1092 regs = get_ESRs(frame)
1093 for reg in regs:
Zachary Turner35d017f2015-10-23 17:04:29 +00001094 print("%s => %s" % (reg.GetName(), reg.GetValue()))
Johnny Chene9e86892011-05-10 23:01:44 +00001095 ...
Johnny Chen64ff7e62011-05-10 19:21:13 +00001096 """
1097 return get_registers(frame, "exception state")
Johnny Chen989b7ef2011-07-22 00:47:58 +00001098
Johnny Chenefee1cd2011-07-22 00:51:54 +00001099# ======================================
1100# Utility classes/functions for SBValues
1101# ======================================
Johnny Chen989b7ef2011-07-22 00:47:58 +00001102
Kate Stoneb9c1b512016-09-06 20:57:50 +00001103
Johnny Chen989b7ef2011-07-22 00:47:58 +00001104class BasicFormatter(object):
Johnny Chen36d7d912011-07-22 22:01:35 +00001105 """The basic formatter inspects the value object and prints the value."""
Kate Stoneb9c1b512016-09-06 20:57:50 +00001106
Johnny Chen989b7ef2011-07-22 00:47:58 +00001107 def format(self, value, buffer=None, indent=0):
1108 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +00001109 output = SixStringIO()
Johnny Chen989b7ef2011-07-22 00:47:58 +00001110 else:
1111 output = buffer
Johnny Chen36d7d912011-07-22 22:01:35 +00001112 # If there is a summary, it suffices.
1113 val = value.GetSummary()
1114 # Otherwise, get the value.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001115 if val is None:
Johnny Chen36d7d912011-07-22 22:01:35 +00001116 val = value.GetValue()
Kate Stoneb9c1b512016-09-06 20:57:50 +00001117 if val is None and value.GetNumChildren() > 0:
Johnny Chen36d7d912011-07-22 22:01:35 +00001118 val = "%s (location)" % value.GetLocation()
Zachary Turnerff890da2015-10-19 23:45:41 +00001119 print("{indentation}({type}) {name} = {value}".format(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001120 indentation=' ' * indent,
1121 type=value.GetTypeName(),
1122 name=value.GetName(),
1123 value=val), file=output)
Johnny Chen989b7ef2011-07-22 00:47:58 +00001124 return output.getvalue()
1125
Kate Stoneb9c1b512016-09-06 20:57:50 +00001126
Johnny Chen989b7ef2011-07-22 00:47:58 +00001127class ChildVisitingFormatter(BasicFormatter):
Johnny Chen36d7d912011-07-22 22:01:35 +00001128 """The child visiting formatter prints the value and its immediate children.
1129
1130 The constructor takes a keyword arg: indent_child, which defaults to 2.
1131 """
Kate Stoneb9c1b512016-09-06 20:57:50 +00001132
Johnny Chen36d7d912011-07-22 22:01:35 +00001133 def __init__(self, indent_child=2):
1134 """Default indentation of 2 SPC's for the children."""
1135 self.cindent = indent_child
Kate Stoneb9c1b512016-09-06 20:57:50 +00001136
Johnny Chen989b7ef2011-07-22 00:47:58 +00001137 def format(self, value, buffer=None):
1138 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +00001139 output = SixStringIO()
Johnny Chen989b7ef2011-07-22 00:47:58 +00001140 else:
1141 output = buffer
1142
1143 BasicFormatter.format(self, value, buffer=output)
1144 for child in value:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001145 BasicFormatter.format(
1146 self, child, buffer=output, indent=self.cindent)
Johnny Chen36d7d912011-07-22 22:01:35 +00001147
1148 return output.getvalue()
1149
Kate Stoneb9c1b512016-09-06 20:57:50 +00001150
Johnny Chen36d7d912011-07-22 22:01:35 +00001151class RecursiveDecentFormatter(BasicFormatter):
1152 """The recursive decent formatter prints the value and the decendents.
1153
1154 The constructor takes two keyword args: indent_level, which defaults to 0,
1155 and indent_child, which defaults to 2. The current indentation level is
1156 determined by indent_level, while the immediate children has an additional
Kate Stoneb9c1b512016-09-06 20:57:50 +00001157 indentation by inden_child.
Johnny Chen36d7d912011-07-22 22:01:35 +00001158 """
Kate Stoneb9c1b512016-09-06 20:57:50 +00001159
Johnny Chen36d7d912011-07-22 22:01:35 +00001160 def __init__(self, indent_level=0, indent_child=2):
1161 self.lindent = indent_level
1162 self.cindent = indent_child
Kate Stoneb9c1b512016-09-06 20:57:50 +00001163
Johnny Chen36d7d912011-07-22 22:01:35 +00001164 def format(self, value, buffer=None):
1165 if not buffer:
Zachary Turner814236d2015-10-21 17:48:52 +00001166 output = SixStringIO()
Johnny Chen36d7d912011-07-22 22:01:35 +00001167 else:
1168 output = buffer
1169
1170 BasicFormatter.format(self, value, buffer=output, indent=self.lindent)
1171 new_indent = self.lindent + self.cindent
1172 for child in value:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001173 if child.GetSummary() is not None:
1174 BasicFormatter.format(
1175 self, child, buffer=output, indent=new_indent)
Johnny Chen36d7d912011-07-22 22:01:35 +00001176 else:
1177 if child.GetNumChildren() > 0:
1178 rdf = RecursiveDecentFormatter(indent_level=new_indent)
1179 rdf.format(child, buffer=output)
1180 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001181 BasicFormatter.format(
1182 self, child, buffer=output, indent=new_indent)
Johnny Chen989b7ef2011-07-22 00:47:58 +00001183
1184 return output.getvalue()
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001185
1186# ===========================================================
1187# Utility functions for path manipulation on remote platforms
1188# ===========================================================
1189
Kate Stoneb9c1b512016-09-06 20:57:50 +00001190
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001191def join_remote_paths(*paths):
1192 # TODO: update with actual platform name for remote windows once it exists
1193 if lldb.remote_platform.GetName() == 'remote-windows':
1194 return os.path.join(*paths).replace(os.path.sep, '\\')
1195 return os.path.join(*paths).replace(os.path.sep, '/')
1196
Kate Stoneb9c1b512016-09-06 20:57:50 +00001197
Chaoren Lin5d76b1b2015-06-06 00:25:50 +00001198def append_to_process_working_directory(*paths):
1199 remote = lldb.remote_platform
1200 if remote:
1201 return join_remote_paths(remote.GetWorkingDirectory(), *paths)
1202 return os.path.join(os.getcwd(), *paths)
Chaoren Linf59d05092015-06-02 16:46:28 +00001203
1204# ==================================================
1205# Utility functions to get the correct signal number
1206# ==================================================
1207
1208import signal
1209
Kate Stoneb9c1b512016-09-06 20:57:50 +00001210
Chaoren Linf59d05092015-06-02 16:46:28 +00001211def get_signal_number(signal_name):
1212 platform = lldb.remote_platform
Chaoren Lin98d0a4b2015-07-14 01:09:28 +00001213 if platform and platform.IsValid():
1214 signals = platform.GetUnixSignals()
1215 if signals.IsValid():
Chaoren Lin264e5422015-06-02 18:31:57 +00001216 signal_number = signals.GetSignalNumberFromName(signal_name)
1217 if signal_number > 0:
1218 return signal_number
Chaoren Lin98d0a4b2015-07-14 01:09:28 +00001219 # No remote platform; fall back to using local python signals.
Chaoren Linf59d05092015-06-02 16:46:28 +00001220 return getattr(signal, signal_name)
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001221
Kate Stoneb9c1b512016-09-06 20:57:50 +00001222
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001223class PrintableRegex(object):
Kate Stoneb9c1b512016-09-06 20:57:50 +00001224
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001225 def __init__(self, text):
1226 self.regex = re.compile(text)
1227 self.text = text
Kate Stoneb9c1b512016-09-06 20:57:50 +00001228
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001229 def match(self, str):
1230 return self.regex.match(str)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001231
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001232 def __str__(self):
1233 return "%s" % (self.text)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001234
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001235 def __repr__(self):
1236 return "re.compile(%s) -> %s" % (self.text, self.regex)
1237
Kate Stoneb9c1b512016-09-06 20:57:50 +00001238
Enrico Granataef4fa442015-12-04 19:50:05 +00001239def skip_if_callable(test, mycallable, reason):
1240 if six.callable(mycallable):
1241 if mycallable(test):
1242 test.skipTest(reason)
1243 return True
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001244 return False
1245
Kate Stoneb9c1b512016-09-06 20:57:50 +00001246
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001247def skip_if_library_missing(test, target, library):
1248 def find_library(target, library):
1249 for module in target.modules:
1250 filename = module.file.GetFilename()
1251 if isinstance(library, str):
1252 if library == filename:
1253 return False
1254 elif hasattr(library, 'match'):
1255 if library.match(filename):
1256 return False
1257 return True
Kate Stoneb9c1b512016-09-06 20:57:50 +00001258
Enrico Granata0b5a6e32015-09-18 20:12:52 +00001259 def find_library_callable(test):
1260 return find_library(target, library)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001261 return skip_if_callable(
1262 test,
1263 find_library_callable,
1264 "could not find library matching '%s' in target %s" %
1265 (library,
1266 target))
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001267
Kate Stoneb9c1b512016-09-06 20:57:50 +00001268
1269def wait_for_file_on_target(testcase, file_path, max_attempts=6):
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001270 for i in range(max_attempts):
1271 err, retcode, msg = testcase.run_platform_command("ls %s" % file_path)
1272 if err.Success() and retcode == 0:
1273 break
1274 if i < max_attempts:
1275 # Exponential backoff!
Todd Fiala464f7df2016-04-08 18:06:11 +00001276 import time
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001277 time.sleep(pow(2, i) * 0.25)
1278 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001279 testcase.fail(
1280 "File %s not found even after %d attempts." %
1281 (file_path, max_attempts))
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001282
1283 err, retcode, data = testcase.run_platform_command("cat %s" % (file_path))
1284
Kate Stoneb9c1b512016-09-06 20:57:50 +00001285 testcase.assertTrue(
1286 err.Success() and retcode == 0, "Failed to read file %s: %s, retcode: %d" %
1287 (file_path, err.GetCString(), retcode))
Tamas Berghammer19fc1d42016-04-05 14:08:18 +00001288 return data