[PowerPC] Collect some CallLowering arguments into a struct. [NFC]
[llvm-project.git] / lldb / packages / Python / lldbsuite / test / lldbutil.py
blob006362a4479c1a6a60e29e5fcf5d9dd4cbdf497c
1 """
2 This LLDB module contains miscellaneous utilities.
3 Some of the test suite takes advantage of the utility functions defined here.
4 They can also be useful for general purpose lldb scripting.
5 """
7 from __future__ import print_function
8 from __future__ import absolute_import
10 # System modules
11 import errno
12 import os
13 import re
14 import sys
16 # Third-party modules
17 from six import StringIO as SixStringIO
18 import six
20 # LLDB modules
21 import lldb
22 from . import lldbtest_config
25 # ===================================================
26 # Utilities for locating/checking executable programs
27 # ===================================================
29 def is_exe(fpath):
30 """Returns True if fpath is an executable."""
31 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
34 def which(program):
35 """Returns the full path to a program; None otherwise."""
36 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
47 def mkdir_p(path):
48 try:
49 os.makedirs(path)
50 except OSError as e:
51 if e.errno != errno.EEXIST:
52 raise
53 if not os.path.isdir(path):
54 raise OSError(errno.ENOTDIR, "%s is not a directory"%path)
55 # ===================================================
56 # Disassembly for an SBFunction or an SBSymbol object
57 # ===================================================
60 def disassemble(target, function_or_symbol):
61 """Disassemble the function or symbol given a target.
63 It returns the disassembly content in a string object.
64 """
65 buf = SixStringIO()
66 insts = function_or_symbol.GetInstructions(target)
67 for i in insts:
68 print(i, file=buf)
69 return buf.getvalue()
71 # ==========================================================
72 # Integer (byte size 1, 2, 4, and 8) to bytearray conversion
73 # ==========================================================
76 def int_to_bytearray(val, bytesize):
77 """Utility function to convert an integer into a bytearray.
79 It returns the bytearray in the little endian format. It is easy to get the
80 big endian format, just do ba.reverse() on the returned object.
81 """
82 import struct
84 if bytesize == 1:
85 return bytearray([val])
87 # Little endian followed by a format character.
88 template = "<%c"
89 if bytesize == 2:
90 fmt = template % 'h'
91 elif bytesize == 4:
92 fmt = template % 'i'
93 elif bytesize == 4:
94 fmt = template % 'q'
95 else:
96 return None
98 packed = struct.pack(fmt, val)
99 return bytearray(packed)
102 def bytearray_to_int(bytes, bytesize):
103 """Utility function to convert a bytearray into an integer.
105 It interprets the bytearray in the little endian format. For a big endian
106 bytearray, just do ba.reverse() on the object before passing it in.
108 import struct
110 if bytesize == 1:
111 return bytes[0]
113 # Little endian followed by a format character.
114 template = "<%c"
115 if bytesize == 2:
116 fmt = template % 'h'
117 elif bytesize == 4:
118 fmt = template % 'i'
119 elif bytesize == 4:
120 fmt = template % 'q'
121 else:
122 return None
124 unpacked = struct.unpack_from(fmt, bytes)
125 return unpacked[0]
128 # ==============================================================
129 # Get the description of an lldb object or None if not available
130 # ==============================================================
131 def get_description(obj, option=None):
132 """Calls lldb_obj.GetDescription() and returns a string, or None.
134 For SBTarget, SBBreakpointLocation, and SBWatchpoint lldb objects, an extra
135 option can be passed in to describe the detailed level of description
136 desired:
137 o lldb.eDescriptionLevelBrief
138 o lldb.eDescriptionLevelFull
139 o lldb.eDescriptionLevelVerbose
141 method = getattr(obj, 'GetDescription')
142 if not method:
143 return None
144 tuple = (lldb.SBTarget, lldb.SBBreakpointLocation, lldb.SBWatchpoint)
145 if isinstance(obj, tuple):
146 if option is None:
147 option = lldb.eDescriptionLevelBrief
149 stream = lldb.SBStream()
150 if option is None:
151 success = method(stream)
152 else:
153 success = method(stream, option)
154 if not success:
155 return None
156 return stream.GetData()
159 # =================================================
160 # Convert some enum value to its string counterpart
161 # =================================================
163 def state_type_to_str(enum):
164 """Returns the stateType string given an enum."""
165 if enum == lldb.eStateInvalid:
166 return "invalid"
167 elif enum == lldb.eStateUnloaded:
168 return "unloaded"
169 elif enum == lldb.eStateConnected:
170 return "connected"
171 elif enum == lldb.eStateAttaching:
172 return "attaching"
173 elif enum == lldb.eStateLaunching:
174 return "launching"
175 elif enum == lldb.eStateStopped:
176 return "stopped"
177 elif enum == lldb.eStateRunning:
178 return "running"
179 elif enum == lldb.eStateStepping:
180 return "stepping"
181 elif enum == lldb.eStateCrashed:
182 return "crashed"
183 elif enum == lldb.eStateDetached:
184 return "detached"
185 elif enum == lldb.eStateExited:
186 return "exited"
187 elif enum == lldb.eStateSuspended:
188 return "suspended"
189 else:
190 raise Exception("Unknown StateType enum")
193 def stop_reason_to_str(enum):
194 """Returns the stopReason string given an enum."""
195 if enum == lldb.eStopReasonInvalid:
196 return "invalid"
197 elif enum == lldb.eStopReasonNone:
198 return "none"
199 elif enum == lldb.eStopReasonTrace:
200 return "trace"
201 elif enum == lldb.eStopReasonBreakpoint:
202 return "breakpoint"
203 elif enum == lldb.eStopReasonWatchpoint:
204 return "watchpoint"
205 elif enum == lldb.eStopReasonExec:
206 return "exec"
207 elif enum == lldb.eStopReasonSignal:
208 return "signal"
209 elif enum == lldb.eStopReasonException:
210 return "exception"
211 elif enum == lldb.eStopReasonPlanComplete:
212 return "plancomplete"
213 elif enum == lldb.eStopReasonThreadExiting:
214 return "threadexiting"
215 else:
216 raise Exception("Unknown StopReason enum")
219 def symbol_type_to_str(enum):
220 """Returns the symbolType string given an enum."""
221 if enum == lldb.eSymbolTypeInvalid:
222 return "invalid"
223 elif enum == lldb.eSymbolTypeAbsolute:
224 return "absolute"
225 elif enum == lldb.eSymbolTypeCode:
226 return "code"
227 elif enum == lldb.eSymbolTypeData:
228 return "data"
229 elif enum == lldb.eSymbolTypeTrampoline:
230 return "trampoline"
231 elif enum == lldb.eSymbolTypeRuntime:
232 return "runtime"
233 elif enum == lldb.eSymbolTypeException:
234 return "exception"
235 elif enum == lldb.eSymbolTypeSourceFile:
236 return "sourcefile"
237 elif enum == lldb.eSymbolTypeHeaderFile:
238 return "headerfile"
239 elif enum == lldb.eSymbolTypeObjectFile:
240 return "objectfile"
241 elif enum == lldb.eSymbolTypeCommonBlock:
242 return "commonblock"
243 elif enum == lldb.eSymbolTypeBlock:
244 return "block"
245 elif enum == lldb.eSymbolTypeLocal:
246 return "local"
247 elif enum == lldb.eSymbolTypeParam:
248 return "param"
249 elif enum == lldb.eSymbolTypeVariable:
250 return "variable"
251 elif enum == lldb.eSymbolTypeVariableType:
252 return "variabletype"
253 elif enum == lldb.eSymbolTypeLineEntry:
254 return "lineentry"
255 elif enum == lldb.eSymbolTypeLineHeader:
256 return "lineheader"
257 elif enum == lldb.eSymbolTypeScopeBegin:
258 return "scopebegin"
259 elif enum == lldb.eSymbolTypeScopeEnd:
260 return "scopeend"
261 elif enum == lldb.eSymbolTypeAdditional:
262 return "additional"
263 elif enum == lldb.eSymbolTypeCompiler:
264 return "compiler"
265 elif enum == lldb.eSymbolTypeInstrumentation:
266 return "instrumentation"
267 elif enum == lldb.eSymbolTypeUndefined:
268 return "undefined"
271 def value_type_to_str(enum):
272 """Returns the valueType string given an enum."""
273 if enum == lldb.eValueTypeInvalid:
274 return "invalid"
275 elif enum == lldb.eValueTypeVariableGlobal:
276 return "global_variable"
277 elif enum == lldb.eValueTypeVariableStatic:
278 return "static_variable"
279 elif enum == lldb.eValueTypeVariableArgument:
280 return "argument_variable"
281 elif enum == lldb.eValueTypeVariableLocal:
282 return "local_variable"
283 elif enum == lldb.eValueTypeRegister:
284 return "register"
285 elif enum == lldb.eValueTypeRegisterSet:
286 return "register_set"
287 elif enum == lldb.eValueTypeConstResult:
288 return "constant_result"
289 else:
290 raise Exception("Unknown ValueType enum")
293 # ==================================================
294 # Get stopped threads due to each stop reason.
295 # ==================================================
297 def sort_stopped_threads(process,
298 breakpoint_threads=None,
299 crashed_threads=None,
300 watchpoint_threads=None,
301 signal_threads=None,
302 exiting_threads=None,
303 other_threads=None):
304 """ Fills array *_threads with threads stopped for the corresponding stop
305 reason.
307 for lst in [breakpoint_threads,
308 watchpoint_threads,
309 signal_threads,
310 exiting_threads,
311 other_threads]:
312 if lst is not None:
313 lst[:] = []
315 for thread in process:
316 dispatched = False
317 for (reason, list) in [(lldb.eStopReasonBreakpoint, breakpoint_threads),
318 (lldb.eStopReasonException, crashed_threads),
319 (lldb.eStopReasonWatchpoint, watchpoint_threads),
320 (lldb.eStopReasonSignal, signal_threads),
321 (lldb.eStopReasonThreadExiting, exiting_threads),
322 (None, other_threads)]:
323 if not dispatched and list is not None:
324 if thread.GetStopReason() == reason or reason is None:
325 list.append(thread)
326 dispatched = True
328 # ==================================================
329 # Utility functions for setting breakpoints
330 # ==================================================
332 def run_break_set_by_script(
333 test,
334 class_name,
335 extra_options=None,
336 num_expected_locations=1):
337 """Set a scripted breakpoint. Check that it got the right number of locations."""
338 test.assertTrue(class_name is not None, "Must pass in a class name.")
339 command = "breakpoint set -P " + class_name
340 if extra_options is not None:
341 command += " " + extra_options
343 break_results = run_break_set_command(test, command)
344 check_breakpoint_result(test, break_results, num_locations=num_expected_locations)
345 return get_bpno_from_match(break_results)
347 def run_break_set_by_file_and_line(
348 test,
349 file_name,
350 line_number,
351 extra_options=None,
352 num_expected_locations=1,
353 loc_exact=False,
354 module_name=None):
355 """Set a breakpoint by file and line, returning the breakpoint number.
357 If extra_options is not None, then we append it to the breakpoint set command.
359 If num_expected_locations is -1, we check that we got AT LEAST one location. If num_expected_locations is -2, we don't
360 check the actual number at all. Otherwise, we check that num_expected_locations equals the number of locations.
362 If loc_exact is true, we check that there is one location, and that location must be at the input file and line number."""
364 if file_name is None:
365 command = 'breakpoint set -l %d' % (line_number)
366 else:
367 command = 'breakpoint set -f "%s" -l %d' % (file_name, line_number)
369 if module_name:
370 command += " --shlib '%s'" % (module_name)
372 if extra_options:
373 command += " " + extra_options
375 break_results = run_break_set_command(test, command)
377 if num_expected_locations == 1 and loc_exact:
378 check_breakpoint_result(
379 test,
380 break_results,
381 num_locations=num_expected_locations,
382 file_name=file_name,
383 line_number=line_number,
384 module_name=module_name)
385 else:
386 check_breakpoint_result(
387 test,
388 break_results,
389 num_locations=num_expected_locations)
391 return get_bpno_from_match(break_results)
394 def run_break_set_by_symbol(
395 test,
396 symbol,
397 extra_options=None,
398 num_expected_locations=-1,
399 sym_exact=False,
400 module_name=None):
401 """Set a breakpoint by symbol name. Common options are the same as run_break_set_by_file_and_line.
403 If sym_exact is true, then the output symbol must match the input exactly, otherwise we do a substring match."""
404 command = 'breakpoint set -n "%s"' % (symbol)
406 if module_name:
407 command += " --shlib '%s'" % (module_name)
409 if extra_options:
410 command += " " + extra_options
412 break_results = run_break_set_command(test, command)
414 if num_expected_locations == 1 and sym_exact:
415 check_breakpoint_result(
416 test,
417 break_results,
418 num_locations=num_expected_locations,
419 symbol_name=symbol,
420 module_name=module_name)
421 else:
422 check_breakpoint_result(
423 test,
424 break_results,
425 num_locations=num_expected_locations)
427 return get_bpno_from_match(break_results)
430 def run_break_set_by_selector(
431 test,
432 selector,
433 extra_options=None,
434 num_expected_locations=-1,
435 module_name=None):
436 """Set a breakpoint by selector. Common options are the same as run_break_set_by_file_and_line."""
438 command = 'breakpoint set -S "%s"' % (selector)
440 if module_name:
441 command += ' --shlib "%s"' % (module_name)
443 if extra_options:
444 command += " " + extra_options
446 break_results = run_break_set_command(test, command)
448 if num_expected_locations == 1:
449 check_breakpoint_result(
450 test,
451 break_results,
452 num_locations=num_expected_locations,
453 symbol_name=selector,
454 symbol_match_exact=False,
455 module_name=module_name)
456 else:
457 check_breakpoint_result(
458 test,
459 break_results,
460 num_locations=num_expected_locations)
462 return get_bpno_from_match(break_results)
465 def run_break_set_by_regexp(
466 test,
467 regexp,
468 extra_options=None,
469 num_expected_locations=-1):
470 """Set a breakpoint by regular expression match on symbol name. Common options are the same as run_break_set_by_file_and_line."""
472 command = 'breakpoint set -r "%s"' % (regexp)
473 if extra_options:
474 command += " " + extra_options
476 break_results = run_break_set_command(test, command)
478 check_breakpoint_result(
479 test,
480 break_results,
481 num_locations=num_expected_locations)
483 return get_bpno_from_match(break_results)
486 def run_break_set_by_source_regexp(
487 test,
488 regexp,
489 extra_options=None,
490 num_expected_locations=-1):
491 """Set a breakpoint by source regular expression. Common options are the same as run_break_set_by_file_and_line."""
492 command = 'breakpoint set -p "%s"' % (regexp)
493 if extra_options:
494 command += " " + extra_options
496 break_results = run_break_set_command(test, command)
498 check_breakpoint_result(
499 test,
500 break_results,
501 num_locations=num_expected_locations)
503 return get_bpno_from_match(break_results)
506 def run_break_set_command(test, command):
507 """Run the command passed in - it must be some break set variant - and analyze the result.
508 Returns a dictionary of information gleaned from the command-line results.
509 Will assert if the breakpoint setting fails altogether.
511 Dictionary will contain:
512 bpno - breakpoint of the newly created breakpoint, -1 on error.
513 num_locations - number of locations set for the breakpoint.
515 If there is only one location, the dictionary MAY contain:
516 file - source file name
517 line_no - source line number
518 symbol - symbol name
519 inline_symbol - inlined symbol name
520 offset - offset from the original symbol
521 module - module
522 address - address at which the breakpoint was set."""
524 patterns = [
525 r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>[0-9]+) locations\.$",
526 r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>no) locations \(pending\)\.",
527 r"^Breakpoint (?P<bpno>[0-9]+): where = (?P<module>.*)`(?P<symbol>[+\-]{0,1}[^+]+)( \+ (?P<offset>[0-9]+)){0,1}( \[inlined\] (?P<inline_symbol>.*)){0,1} at (?P<file>[^:]+):(?P<line_no>[0-9]+)(?P<column>(:[0-9]+)?), address = (?P<address>0x[0-9a-fA-F]+)$",
528 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]+)$"]
529 match_object = test.match(command, patterns)
530 break_results = match_object.groupdict()
532 # We always insert the breakpoint number, setting it to -1 if we couldn't find it
533 # Also, make sure it gets stored as an integer.
534 if not 'bpno' in break_results:
535 break_results['bpno'] = -1
536 else:
537 break_results['bpno'] = int(break_results['bpno'])
539 # We always insert the number of locations
540 # If ONE location is set for the breakpoint, then the output doesn't mention locations, but it has to be 1...
541 # We also make sure it is an integer.
543 if not 'num_locations' in break_results:
544 num_locations = 1
545 else:
546 num_locations = break_results['num_locations']
547 if num_locations == 'no':
548 num_locations = 0
549 else:
550 num_locations = int(break_results['num_locations'])
552 break_results['num_locations'] = num_locations
554 if 'line_no' in break_results:
555 break_results['line_no'] = int(break_results['line_no'])
557 return break_results
560 def get_bpno_from_match(break_results):
561 return int(break_results['bpno'])
564 def check_breakpoint_result(
565 test,
566 break_results,
567 file_name=None,
568 line_number=-1,
569 symbol_name=None,
570 symbol_match_exact=True,
571 module_name=None,
572 offset=-1,
573 num_locations=-1):
575 out_num_locations = break_results['num_locations']
577 if num_locations == -1:
578 test.assertTrue(out_num_locations > 0,
579 "Expecting one or more locations, got none.")
580 elif num_locations != -2:
581 test.assertTrue(
582 num_locations == out_num_locations,
583 "Expecting %d locations, got %d." %
584 (num_locations,
585 out_num_locations))
587 if file_name:
588 out_file_name = ""
589 if 'file' in break_results:
590 out_file_name = break_results['file']
591 test.assertTrue(
592 file_name.endswith(out_file_name),
593 "Breakpoint file name '%s' doesn't match resultant name '%s'." %
594 (file_name,
595 out_file_name))
597 if line_number != -1:
598 out_line_number = -1
599 if 'line_no' in break_results:
600 out_line_number = break_results['line_no']
602 test.assertTrue(
603 line_number == out_line_number,
604 "Breakpoint line number %s doesn't match resultant line %s." %
605 (line_number,
606 out_line_number))
608 if symbol_name:
609 out_symbol_name = ""
610 # Look first for the inlined symbol name, otherwise use the symbol
611 # name:
612 if 'inline_symbol' in break_results and break_results['inline_symbol']:
613 out_symbol_name = break_results['inline_symbol']
614 elif 'symbol' in break_results:
615 out_symbol_name = break_results['symbol']
617 if symbol_match_exact:
618 test.assertTrue(
619 symbol_name == out_symbol_name,
620 "Symbol name '%s' doesn't match resultant symbol '%s'." %
621 (symbol_name,
622 out_symbol_name))
623 else:
624 test.assertTrue(
625 out_symbol_name.find(symbol_name) != -
627 "Symbol name '%s' isn't in resultant symbol '%s'." %
628 (symbol_name,
629 out_symbol_name))
631 if module_name:
632 out_module_name = None
633 if 'module' in break_results:
634 out_module_name = break_results['module']
636 test.assertTrue(
637 module_name.find(out_module_name) != -
639 "Symbol module name '%s' isn't in expected module name '%s'." %
640 (out_module_name,
641 module_name))
643 # ==================================================
644 # Utility functions related to Threads and Processes
645 # ==================================================
648 def get_stopped_threads(process, reason):
649 """Returns the thread(s) with the specified stop reason in a list.
651 The list can be empty if no such thread exists.
653 threads = []
654 for t in process:
655 if t.GetStopReason() == reason:
656 threads.append(t)
657 return threads
660 def get_stopped_thread(process, reason):
661 """A convenience function which returns the first thread with the given stop
662 reason or None.
664 Example usages:
666 1. Get the stopped thread due to a breakpoint condition
669 from lldbutil import get_stopped_thread
670 thread = get_stopped_thread(process, lldb.eStopReasonPlanComplete)
671 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition")
674 2. Get the thread stopped due to a breakpoint
677 from lldbutil import get_stopped_thread
678 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
679 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint")
683 threads = get_stopped_threads(process, reason)
684 if len(threads) == 0:
685 return None
686 return threads[0]
689 def get_threads_stopped_at_breakpoint_id(process, bpid):
690 """ For a stopped process returns the thread stopped at the breakpoint passed in bkpt"""
691 stopped_threads = []
692 threads = []
694 stopped_threads = get_stopped_threads(process, lldb.eStopReasonBreakpoint)
696 if len(stopped_threads) == 0:
697 return threads
699 for thread in stopped_threads:
700 # Make sure we've hit our breakpoint...
701 break_id = thread.GetStopReasonDataAtIndex(0)
702 if break_id == bpid:
703 threads.append(thread)
705 return threads
708 def get_threads_stopped_at_breakpoint(process, bkpt):
709 return get_threads_stopped_at_breakpoint_id(process, bkpt.GetID())
712 def get_one_thread_stopped_at_breakpoint_id(
713 process, bpid, require_exactly_one=True):
714 threads = get_threads_stopped_at_breakpoint_id(process, bpid)
715 if len(threads) == 0:
716 return None
717 if require_exactly_one and len(threads) != 1:
718 return None
720 return threads[0]
723 def get_one_thread_stopped_at_breakpoint(
724 process, bkpt, require_exactly_one=True):
725 return get_one_thread_stopped_at_breakpoint_id(
726 process, bkpt.GetID(), require_exactly_one)
729 def is_thread_crashed(test, thread):
730 """In the test suite we dereference a null pointer to simulate a crash. The way this is
731 reported depends on the platform."""
732 if test.platformIsDarwin():
733 return thread.GetStopReason(
734 ) == lldb.eStopReasonException and "EXC_BAD_ACCESS" in thread.GetStopDescription(100)
735 elif test.getPlatform() == "linux":
736 return thread.GetStopReason() == lldb.eStopReasonSignal and thread.GetStopReasonDataAtIndex(
737 0) == thread.GetProcess().GetUnixSignals().GetSignalNumberFromName("SIGSEGV")
738 elif test.getPlatform() == "windows":
739 return "Exception 0xc0000005" in thread.GetStopDescription(200)
740 else:
741 return "invalid address" in thread.GetStopDescription(100)
744 def get_crashed_threads(test, process):
745 threads = []
746 if process.GetState() != lldb.eStateStopped:
747 return threads
748 for thread in process:
749 if is_thread_crashed(test, thread):
750 threads.append(thread)
751 return threads
753 # Helper functions for run_to_{source,name}_breakpoint:
755 def run_to_breakpoint_make_target(test, exe_name = "a.out", in_cwd = True):
756 if in_cwd:
757 exe = test.getBuildArtifact(exe_name)
759 # Create the target
760 target = test.dbg.CreateTarget(exe)
761 test.assertTrue(target, "Target: %s is not valid."%(exe_name))
763 # Set environment variables for the inferior.
764 if lldbtest_config.inferior_env:
765 test.runCmd('settings set target.env-vars {}'.format(
766 lldbtest_config.inferior_env))
768 return target
770 def run_to_breakpoint_do_run(test, target, bkpt, launch_info = None,
771 only_one_thread = True, extra_images = None):
773 # Launch the process, and do not stop at the entry point.
774 if not launch_info:
775 launch_info = target.GetLaunchInfo()
776 launch_info.SetWorkingDirectory(test.get_process_working_directory())
778 if extra_images and lldb.remote_platform:
779 environ = test.registerSharedLibrariesWithTarget(target, extra_images)
780 launch_info.SetEnvironmentEntries(environ, True)
782 error = lldb.SBError()
783 process = target.Launch(launch_info, error)
785 test.assertTrue(process,
786 "Could not create a valid process for %s: %s"%(target.GetExecutable().GetFilename(),
787 error.GetCString()))
788 test.assertFalse(error.Fail(),
789 "Process launch failed: %s" % (error.GetCString()))
791 # Frame #0 should be at our breakpoint.
792 threads = get_threads_stopped_at_breakpoint(
793 process, bkpt)
795 num_threads = len(threads)
796 if only_one_thread:
797 test.assertEqual(num_threads, 1, "Expected 1 thread to stop at breakpoint, %d did."%(num_threads))
798 else:
799 test.assertGreater(num_threads, 0, "No threads stopped at breakpoint")
801 thread = threads[0]
802 return (target, process, thread, bkpt)
804 def run_to_name_breakpoint (test, bkpt_name, launch_info = None,
805 exe_name = "a.out",
806 bkpt_module = None,
807 in_cwd = True,
808 only_one_thread = True,
809 extra_images = None):
810 """Start up a target, using exe_name as the executable, and run it to
811 a breakpoint set by name on bkpt_name restricted to bkpt_module.
813 If you want to pass in launch arguments or environment
814 variables, you can optionally pass in an SBLaunchInfo. If you
815 do that, remember to set the working directory as well.
817 If your executable isn't called a.out, you can pass that in.
818 And if your executable isn't in the CWD, pass in the absolute
819 path to the executable in exe_name, and set in_cwd to False.
821 If you need to restrict the breakpoint to a particular module,
822 pass the module name (a string not a FileSpec) in bkpt_module. If
823 nothing is passed in setting will be unrestricted.
825 If the target isn't valid, the breakpoint isn't found, or hit, the
826 function will cause a testsuite failure.
828 If successful it returns a tuple with the target process and
829 thread that hit the breakpoint, and the breakpoint that we set
830 for you.
832 If only_one_thread is true, we require that there be only one
833 thread stopped at the breakpoint. Otherwise we only require one
834 or more threads stop there. If there are more than one, we return
835 the first thread that stopped.
838 target = run_to_breakpoint_make_target(test, exe_name, in_cwd)
840 breakpoint = target.BreakpointCreateByName(bkpt_name, bkpt_module)
843 test.assertTrue(breakpoint.GetNumLocations() > 0,
844 "No locations found for name breakpoint: '%s'."%(bkpt_name))
845 return run_to_breakpoint_do_run(test, target, breakpoint, launch_info,
846 only_one_thread, extra_images)
848 def run_to_source_breakpoint(test, bkpt_pattern, source_spec,
849 launch_info = None, exe_name = "a.out",
850 bkpt_module = None,
851 in_cwd = True,
852 only_one_thread = True,
853 extra_images = None):
854 """Start up a target, using exe_name as the executable, and run it to
855 a breakpoint set by source regex bkpt_pattern.
857 The rest of the behavior is the same as run_to_name_breakpoint.
860 target = run_to_breakpoint_make_target(test, exe_name, in_cwd)
861 # Set the breakpoints
862 breakpoint = target.BreakpointCreateBySourceRegex(
863 bkpt_pattern, source_spec, bkpt_module)
864 test.assertTrue(breakpoint.GetNumLocations() > 0,
865 'No locations found for source breakpoint: "%s", file: "%s", dir: "%s"'
866 %(bkpt_pattern, source_spec.GetFilename(), source_spec.GetDirectory()))
867 return run_to_breakpoint_do_run(test, target, breakpoint, launch_info,
868 only_one_thread, extra_images)
870 def run_to_line_breakpoint(test, source_spec, line_number, column = 0,
871 launch_info = None, exe_name = "a.out",
872 bkpt_module = None,
873 in_cwd = True,
874 only_one_thread = True,
875 extra_images = None):
876 """Start up a target, using exe_name as the executable, and run it to
877 a breakpoint set by (source_spec, line_number(, column)).
879 The rest of the behavior is the same as run_to_name_breakpoint.
882 target = run_to_breakpoint_make_target(test, exe_name, in_cwd)
883 # Set the breakpoints
884 breakpoint = target.BreakpointCreateByLocation(
885 source_spec, line_number, column, 0, lldb.SBFileSpecList())
886 test.assertTrue(breakpoint.GetNumLocations() > 0,
887 'No locations found for line breakpoint: "%s:%d(:%d)", dir: "%s"'
888 %(source_spec.GetFilename(), line_number, column,
889 source_spec.GetDirectory()))
890 return run_to_breakpoint_do_run(test, target, breakpoint, launch_info,
891 only_one_thread, extra_images)
894 def continue_to_breakpoint(process, bkpt):
895 """ Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None"""
896 process.Continue()
897 if process.GetState() != lldb.eStateStopped:
898 return None
899 else:
900 return get_threads_stopped_at_breakpoint(process, bkpt)
903 def get_caller_symbol(thread):
905 Returns the symbol name for the call site of the leaf function.
907 depth = thread.GetNumFrames()
908 if depth <= 1:
909 return None
910 caller = thread.GetFrameAtIndex(1).GetSymbol()
911 if caller:
912 return caller.GetName()
913 else:
914 return None
917 def get_function_names(thread):
919 Returns a sequence of function names from the stack frames of this thread.
921 def GetFuncName(i):
922 return thread.GetFrameAtIndex(i).GetFunctionName()
924 return list(map(GetFuncName, list(range(thread.GetNumFrames()))))
927 def get_symbol_names(thread):
929 Returns a sequence of symbols for this thread.
931 def GetSymbol(i):
932 return thread.GetFrameAtIndex(i).GetSymbol().GetName()
934 return list(map(GetSymbol, list(range(thread.GetNumFrames()))))
937 def get_pc_addresses(thread):
939 Returns a sequence of pc addresses for this thread.
941 def GetPCAddress(i):
942 return thread.GetFrameAtIndex(i).GetPCAddress()
944 return list(map(GetPCAddress, list(range(thread.GetNumFrames()))))
947 def get_filenames(thread):
949 Returns a sequence of file names from the stack frames of this thread.
951 def GetFilename(i):
952 return thread.GetFrameAtIndex(
953 i).GetLineEntry().GetFileSpec().GetFilename()
955 return list(map(GetFilename, list(range(thread.GetNumFrames()))))
958 def get_line_numbers(thread):
960 Returns a sequence of line numbers from the stack frames of this thread.
962 def GetLineNumber(i):
963 return thread.GetFrameAtIndex(i).GetLineEntry().GetLine()
965 return list(map(GetLineNumber, list(range(thread.GetNumFrames()))))
968 def get_module_names(thread):
970 Returns a sequence of module names from the stack frames of this thread.
972 def GetModuleName(i):
973 return thread.GetFrameAtIndex(
974 i).GetModule().GetFileSpec().GetFilename()
976 return list(map(GetModuleName, list(range(thread.GetNumFrames()))))
979 def get_stack_frames(thread):
981 Returns a sequence of stack frames for this thread.
983 def GetStackFrame(i):
984 return thread.GetFrameAtIndex(i)
986 return list(map(GetStackFrame, list(range(thread.GetNumFrames()))))
989 def print_stacktrace(thread, string_buffer=False):
990 """Prints a simple stack trace of this thread."""
992 output = SixStringIO() if string_buffer else sys.stdout
993 target = thread.GetProcess().GetTarget()
995 depth = thread.GetNumFrames()
997 mods = get_module_names(thread)
998 funcs = get_function_names(thread)
999 symbols = get_symbol_names(thread)
1000 files = get_filenames(thread)
1001 lines = get_line_numbers(thread)
1002 addrs = get_pc_addresses(thread)
1004 if thread.GetStopReason() != lldb.eStopReasonInvalid:
1005 desc = "stop reason=" + stop_reason_to_str(thread.GetStopReason())
1006 else:
1007 desc = ""
1008 print(
1009 "Stack trace for thread id={0:#x} name={1} queue={2} ".format(
1010 thread.GetThreadID(),
1011 thread.GetName(),
1012 thread.GetQueueName()) + desc,
1013 file=output)
1015 for i in range(depth):
1016 frame = thread.GetFrameAtIndex(i)
1017 function = frame.GetFunction()
1019 load_addr = addrs[i].GetLoadAddress(target)
1020 if not function:
1021 file_addr = addrs[i].GetFileAddress()
1022 start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress()
1023 symbol_offset = file_addr - start_addr
1024 print(
1025 " frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format(
1026 num=i,
1027 addr=load_addr,
1028 mod=mods[i],
1029 symbol=symbols[i],
1030 offset=symbol_offset),
1031 file=output)
1032 else:
1033 print(
1034 " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format(
1035 num=i,
1036 addr=load_addr,
1037 mod=mods[i],
1038 func='%s [inlined]' %
1039 funcs[i] if frame.IsInlined() else funcs[i],
1040 file=files[i],
1041 line=lines[i],
1042 args=get_args_as_string(
1043 frame,
1044 showFuncName=False) if not frame.IsInlined() else '()'),
1045 file=output)
1047 if string_buffer:
1048 return output.getvalue()
1051 def print_stacktraces(process, string_buffer=False):
1052 """Prints the stack traces of all the threads."""
1054 output = SixStringIO() if string_buffer else sys.stdout
1056 print("Stack traces for " + str(process), file=output)
1058 for thread in process:
1059 print(print_stacktrace(thread, string_buffer=True), file=output)
1061 if string_buffer:
1062 return output.getvalue()
1065 def expect_state_changes(test, listener, process, states, timeout=5):
1066 """Listens for state changed events on the listener and makes sure they match what we
1067 expect. Stop-and-restart events (where GetRestartedFromEvent() returns true) are ignored."""
1069 for expected_state in states:
1070 def get_next_event():
1071 event = lldb.SBEvent()
1072 if not listener.WaitForEventForBroadcasterWithType(
1073 timeout,
1074 process.GetBroadcaster(),
1075 lldb.SBProcess.eBroadcastBitStateChanged,
1076 event):
1077 test.fail(
1078 "Timed out while waiting for a transition to state %s" %
1079 lldb.SBDebugger.StateAsCString(expected_state))
1080 return event
1082 event = get_next_event()
1083 while (lldb.SBProcess.GetStateFromEvent(event) == lldb.eStateStopped and
1084 lldb.SBProcess.GetRestartedFromEvent(event)):
1085 # Ignore restarted event and the subsequent running event.
1086 event = get_next_event()
1087 test.assertEqual(
1088 lldb.SBProcess.GetStateFromEvent(event),
1089 lldb.eStateRunning,
1090 "Restarted event followed by a running event")
1091 event = get_next_event()
1093 test.assertEqual(
1094 lldb.SBProcess.GetStateFromEvent(event),
1095 expected_state)
1097 # ===================================
1098 # Utility functions related to Frames
1099 # ===================================
1102 def get_parent_frame(frame):
1104 Returns the parent frame of the input frame object; None if not available.
1106 thread = frame.GetThread()
1107 parent_found = False
1108 for f in thread:
1109 if parent_found:
1110 return f
1111 if f.GetFrameID() == frame.GetFrameID():
1112 parent_found = True
1114 # If we reach here, no parent has been found, return None.
1115 return None
1118 def get_args_as_string(frame, showFuncName=True):
1120 Returns the args of the input frame object as a string.
1122 # arguments => True
1123 # locals => False
1124 # statics => False
1125 # in_scope_only => True
1126 vars = frame.GetVariables(True, False, False, True) # type of SBValueList
1127 args = [] # list of strings
1128 for var in vars:
1129 args.append("(%s)%s=%s" % (var.GetTypeName(),
1130 var.GetName(),
1131 var.GetValue()))
1132 if frame.GetFunction():
1133 name = frame.GetFunction().GetName()
1134 elif frame.GetSymbol():
1135 name = frame.GetSymbol().GetName()
1136 else:
1137 name = ""
1138 if showFuncName:
1139 return "%s(%s)" % (name, ", ".join(args))
1140 else:
1141 return "(%s)" % (", ".join(args))
1144 def print_registers(frame, string_buffer=False):
1145 """Prints all the register sets of the frame."""
1147 output = SixStringIO() if string_buffer else sys.stdout
1149 print("Register sets for " + str(frame), file=output)
1151 registerSet = frame.GetRegisters() # Return type of SBValueList.
1152 print("Frame registers (size of register set = %d):" %
1153 registerSet.GetSize(), file=output)
1154 for value in registerSet:
1155 #print(value, file=output)
1156 print("%s (number of children = %d):" %
1157 (value.GetName(), value.GetNumChildren()), file=output)
1158 for child in value:
1159 print(
1160 "Name: %s, Value: %s" %
1161 (child.GetName(),
1162 child.GetValue()),
1163 file=output)
1165 if string_buffer:
1166 return output.getvalue()
1169 def get_registers(frame, kind):
1170 """Returns the registers given the frame and the kind of registers desired.
1172 Returns None if there's no such kind.
1174 registerSet = frame.GetRegisters() # Return type of SBValueList.
1175 for value in registerSet:
1176 if kind.lower() in value.GetName().lower():
1177 return value
1179 return None
1182 def get_GPRs(frame):
1183 """Returns the general purpose registers of the frame as an SBValue.
1185 The returned SBValue object is iterable. An example:
1187 from lldbutil import get_GPRs
1188 regs = get_GPRs(frame)
1189 for reg in regs:
1190 print("%s => %s" % (reg.GetName(), reg.GetValue()))
1193 return get_registers(frame, "general purpose")
1196 def get_FPRs(frame):
1197 """Returns the floating point registers of the frame as an SBValue.
1199 The returned SBValue object is iterable. An example:
1201 from lldbutil import get_FPRs
1202 regs = get_FPRs(frame)
1203 for reg in regs:
1204 print("%s => %s" % (reg.GetName(), reg.GetValue()))
1207 return get_registers(frame, "floating point")
1210 def get_ESRs(frame):
1211 """Returns the exception state registers of the frame as an SBValue.
1213 The returned SBValue object is iterable. An example:
1215 from lldbutil import get_ESRs
1216 regs = get_ESRs(frame)
1217 for reg in regs:
1218 print("%s => %s" % (reg.GetName(), reg.GetValue()))
1221 return get_registers(frame, "exception state")
1223 # ======================================
1224 # Utility classes/functions for SBValues
1225 # ======================================
1228 class BasicFormatter(object):
1229 """The basic formatter inspects the value object and prints the value."""
1231 def format(self, value, buffer=None, indent=0):
1232 if not buffer:
1233 output = SixStringIO()
1234 else:
1235 output = buffer
1236 # If there is a summary, it suffices.
1237 val = value.GetSummary()
1238 # Otherwise, get the value.
1239 if val is None:
1240 val = value.GetValue()
1241 if val is None and value.GetNumChildren() > 0:
1242 val = "%s (location)" % value.GetLocation()
1243 print("{indentation}({type}) {name} = {value}".format(
1244 indentation=' ' * indent,
1245 type=value.GetTypeName(),
1246 name=value.GetName(),
1247 value=val), file=output)
1248 return output.getvalue()
1251 class ChildVisitingFormatter(BasicFormatter):
1252 """The child visiting formatter prints the value and its immediate children.
1254 The constructor takes a keyword arg: indent_child, which defaults to 2.
1257 def __init__(self, indent_child=2):
1258 """Default indentation of 2 SPC's for the children."""
1259 self.cindent = indent_child
1261 def format(self, value, buffer=None):
1262 if not buffer:
1263 output = SixStringIO()
1264 else:
1265 output = buffer
1267 BasicFormatter.format(self, value, buffer=output)
1268 for child in value:
1269 BasicFormatter.format(
1270 self, child, buffer=output, indent=self.cindent)
1272 return output.getvalue()
1275 class RecursiveDecentFormatter(BasicFormatter):
1276 """The recursive decent formatter prints the value and the decendents.
1278 The constructor takes two keyword args: indent_level, which defaults to 0,
1279 and indent_child, which defaults to 2. The current indentation level is
1280 determined by indent_level, while the immediate children has an additional
1281 indentation by inden_child.
1284 def __init__(self, indent_level=0, indent_child=2):
1285 self.lindent = indent_level
1286 self.cindent = indent_child
1288 def format(self, value, buffer=None):
1289 if not buffer:
1290 output = SixStringIO()
1291 else:
1292 output = buffer
1294 BasicFormatter.format(self, value, buffer=output, indent=self.lindent)
1295 new_indent = self.lindent + self.cindent
1296 for child in value:
1297 if child.GetSummary() is not None:
1298 BasicFormatter.format(
1299 self, child, buffer=output, indent=new_indent)
1300 else:
1301 if child.GetNumChildren() > 0:
1302 rdf = RecursiveDecentFormatter(indent_level=new_indent)
1303 rdf.format(child, buffer=output)
1304 else:
1305 BasicFormatter.format(
1306 self, child, buffer=output, indent=new_indent)
1308 return output.getvalue()
1310 # ===========================================================
1311 # Utility functions for path manipulation on remote platforms
1312 # ===========================================================
1315 def join_remote_paths(*paths):
1316 # TODO: update with actual platform name for remote windows once it exists
1317 if lldb.remote_platform.GetName() == 'remote-windows':
1318 return os.path.join(*paths).replace(os.path.sep, '\\')
1319 return os.path.join(*paths).replace(os.path.sep, '/')
1322 def append_to_process_working_directory(test, *paths):
1323 remote = lldb.remote_platform
1324 if remote:
1325 return join_remote_paths(remote.GetWorkingDirectory(), *paths)
1326 return os.path.join(test.getBuildDir(), *paths)
1328 # ==================================================
1329 # Utility functions to get the correct signal number
1330 # ==================================================
1332 import signal
1335 def get_signal_number(signal_name):
1336 platform = lldb.remote_platform
1337 if platform and platform.IsValid():
1338 signals = platform.GetUnixSignals()
1339 if signals.IsValid():
1340 signal_number = signals.GetSignalNumberFromName(signal_name)
1341 if signal_number > 0:
1342 return signal_number
1343 # No remote platform; fall back to using local python signals.
1344 return getattr(signal, signal_name)
1347 class PrintableRegex(object):
1349 def __init__(self, text):
1350 self.regex = re.compile(text)
1351 self.text = text
1353 def match(self, str):
1354 return self.regex.match(str)
1356 def __str__(self):
1357 return "%s" % (self.text)
1359 def __repr__(self):
1360 return "re.compile(%s) -> %s" % (self.text, self.regex)
1363 def skip_if_callable(test, mycallable, reason):
1364 if six.callable(mycallable):
1365 if mycallable(test):
1366 test.skipTest(reason)
1367 return True
1368 return False
1371 def skip_if_library_missing(test, target, library):
1372 def find_library(target, library):
1373 for module in target.modules:
1374 filename = module.file.GetFilename()
1375 if isinstance(library, str):
1376 if library == filename:
1377 return False
1378 elif hasattr(library, 'match'):
1379 if library.match(filename):
1380 return False
1381 return True
1383 def find_library_callable(test):
1384 return find_library(target, library)
1385 return skip_if_callable(
1386 test,
1387 find_library_callable,
1388 "could not find library matching '%s' in target %s" %
1389 (library,
1390 target))
1393 def read_file_on_target(test, remote):
1394 if lldb.remote_platform:
1395 local = test.getBuildArtifact("file_from_target")
1396 error = lldb.remote_platform.Get(lldb.SBFileSpec(remote, False),
1397 lldb.SBFileSpec(local, True))
1398 test.assertTrue(error.Success(), "Reading file {0} failed: {1}".format(remote, error))
1399 else:
1400 local = remote
1401 with open(local, 'r') as f:
1402 return f.read()
1404 def read_file_from_process_wd(test, name):
1405 path = append_to_process_working_directory(test, name)
1406 return read_file_on_target(test, path)
1408 def wait_for_file_on_target(testcase, file_path, max_attempts=6):
1409 for i in range(max_attempts):
1410 err, retcode, msg = testcase.run_platform_command("ls %s" % file_path)
1411 if err.Success() and retcode == 0:
1412 break
1413 if i < max_attempts:
1414 # Exponential backoff!
1415 import time
1416 time.sleep(pow(2, i) * 0.25)
1417 else:
1418 testcase.fail(
1419 "File %s not found even after %d attempts." %
1420 (file_path, max_attempts))
1422 return read_file_on_target(testcase, file_path)