[NFC][LLVM][CodeGen] Move LiveDebugVariables.h into llvm/include/llvm/CodeGen (#88374)
[llvm-project.git] / lldb / packages / Python / lldbsuite / test / lldbutil.py
blob58eb37fd742d735a3c1b22d6659a626c0b410eba
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 # System modules
8 import errno
9 import io
10 import os
11 import re
12 import sys
13 import subprocess
14 from typing import Dict
16 # LLDB modules
17 import lldb
18 from . import lldbtest_config
19 from . import configuration
21 # How often failed simulator process launches are retried.
22 SIMULATOR_RETRY = 3
24 # ===================================================
25 # Utilities for locating/checking executable programs
26 # ===================================================
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
48 def mkdir_p(path):
49 try:
50 os.makedirs(path)
51 except OSError as e:
52 if e.errno != errno.EEXIST:
53 raise
54 if not os.path.isdir(path):
55 raise OSError(errno.ENOTDIR, "%s is not a directory" % path)
58 # ============================
59 # Dealing with SDK and triples
60 # ============================
63 def get_xcode_sdk(os, env):
64 # Respect --apple-sdk <path> if it's specified. If the SDK is simply
65 # mounted from some disk image, and not actually installed, this is the
66 # only way to use it.
67 if configuration.apple_sdk:
68 return configuration.apple_sdk
69 if os == "ios":
70 if env == "simulator":
71 return "iphonesimulator"
72 if env == "macabi":
73 return "macosx"
74 return "iphoneos"
75 elif os == "tvos":
76 if env == "simulator":
77 return "appletvsimulator"
78 return "appletvos"
79 elif os == "watchos":
80 if env == "simulator":
81 return "watchsimulator"
82 return "watchos"
83 return os
86 def get_xcode_sdk_version(sdk):
87 return (
88 subprocess.check_output(["xcrun", "--sdk", sdk, "--show-sdk-version"])
89 .rstrip()
90 .decode("utf-8")
94 def get_xcode_sdk_root(sdk):
95 return (
96 subprocess.check_output(["xcrun", "--sdk", sdk, "--show-sdk-path"])
97 .rstrip()
98 .decode("utf-8")
102 def get_xcode_clang(sdk):
103 return (
104 subprocess.check_output(["xcrun", "-sdk", sdk, "-f", "clang"])
105 .rstrip()
106 .decode("utf-8")
110 # ===================================================
111 # Disassembly for an SBFunction or an SBSymbol object
112 # ===================================================
115 def disassemble(target, function_or_symbol):
116 """Disassemble the function or symbol given a target.
118 It returns the disassembly content in a string object.
120 buf = io.StringIO()
121 insts = function_or_symbol.GetInstructions(target)
122 for i in insts:
123 print(i, file=buf)
124 return buf.getvalue()
127 # ==========================================================
128 # Integer (byte size 1, 2, 4, and 8) to bytearray conversion
129 # ==========================================================
132 def int_to_bytearray(val, bytesize):
133 """Utility function to convert an integer into a bytearray.
135 It returns the bytearray in the little endian format. It is easy to get the
136 big endian format, just do ba.reverse() on the returned object.
138 import struct
140 if bytesize == 1:
141 return bytearray([val])
143 # Little endian followed by a format character.
144 template = "<%c"
145 if bytesize == 2:
146 fmt = template % "h"
147 elif bytesize == 4:
148 fmt = template % "i"
149 elif bytesize == 4:
150 fmt = template % "q"
151 else:
152 return None
154 packed = struct.pack(fmt, val)
155 return bytearray(packed)
158 def bytearray_to_int(bytes, bytesize):
159 """Utility function to convert a bytearray into an integer.
161 It interprets the bytearray in the little endian format. For a big endian
162 bytearray, just do ba.reverse() on the object before passing it in.
164 import struct
166 if bytesize == 1:
167 return bytes[0]
169 # Little endian followed by a format character.
170 template = "<%c"
171 if bytesize == 2:
172 fmt = template % "h"
173 elif bytesize == 4:
174 fmt = template % "i"
175 elif bytesize == 4:
176 fmt = template % "q"
177 else:
178 return None
180 unpacked = struct.unpack_from(fmt, bytes)
181 return unpacked[0]
184 # ==============================================================
185 # Get the description of an lldb object or None if not available
186 # ==============================================================
187 def get_description(obj, option=None):
188 """Calls lldb_obj.GetDescription() and returns a string, or None.
190 For SBTarget, SBBreakpointLocation, and SBWatchpoint lldb objects, an extra
191 option can be passed in to describe the detailed level of description
192 desired:
193 o lldb.eDescriptionLevelBrief
194 o lldb.eDescriptionLevelFull
195 o lldb.eDescriptionLevelVerbose
197 method = getattr(obj, "GetDescription")
198 if not method:
199 return None
200 tuple = (lldb.SBTarget, lldb.SBBreakpointLocation, lldb.SBWatchpoint)
201 if isinstance(obj, tuple):
202 if option is None:
203 option = lldb.eDescriptionLevelBrief
205 stream = lldb.SBStream()
206 if option is None:
207 success = method(stream)
208 else:
209 success = method(stream, option)
210 if not success:
211 return None
212 return stream.GetData()
215 # =================================================
216 # Convert some enum value to its string counterpart
217 # =================================================
220 def _enum_names(prefix: str) -> Dict[int, str]:
221 """Generate a mapping of enum value to name, for the enum prefix."""
222 suffix_start = len(prefix)
223 return {
224 getattr(lldb, attr): attr[suffix_start:].lower()
225 for attr in dir(lldb)
226 if attr.startswith(prefix)
230 _STATE_NAMES = _enum_names(prefix="eState")
233 def state_type_to_str(enum: int) -> str:
234 """Returns the stateType string given an enum."""
235 name = _STATE_NAMES.get(enum)
236 if name:
237 return name
238 raise Exception(f"Unknown StateType enum: {enum}")
241 _STOP_REASON_NAMES = _enum_names(prefix="eStopReason")
244 def stop_reason_to_str(enum: int) -> str:
245 """Returns the stopReason string given an enum."""
246 name = _STOP_REASON_NAMES.get(enum)
247 if name:
248 return name
249 raise Exception(f"Unknown StopReason enum: {enum}")
252 _SYMBOL_TYPE_NAMES = _enum_names(prefix="eSymbolType")
255 def symbol_type_to_str(enum: int) -> str:
256 """Returns the symbolType string given an enum."""
257 name = _SYMBOL_TYPE_NAMES.get(enum)
258 if name:
259 return name
260 raise Exception(f"Unknown SymbolType enum: {enum}")
263 _VALUE_TYPE_NAMES = _enum_names(prefix="eValueType")
266 def value_type_to_str(enum: int) -> str:
267 """Returns the valueType string given an enum."""
268 name = _VALUE_TYPE_NAMES.get(enum)
269 if name:
270 return name
271 raise Exception(f"Unknown ValueType enum: {enum}")
274 # ==================================================
275 # Get stopped threads due to each stop reason.
276 # ==================================================
279 def sort_stopped_threads(
280 process,
281 breakpoint_threads=None,
282 crashed_threads=None,
283 watchpoint_threads=None,
284 signal_threads=None,
285 exiting_threads=None,
286 other_threads=None,
288 """Fills array *_threads with threads stopped for the corresponding stop
289 reason.
291 for lst in [
292 breakpoint_threads,
293 watchpoint_threads,
294 signal_threads,
295 exiting_threads,
296 other_threads,
298 if lst is not None:
299 lst[:] = []
301 for thread in process:
302 dispatched = False
303 for reason, list in [
304 (lldb.eStopReasonBreakpoint, breakpoint_threads),
305 (lldb.eStopReasonException, crashed_threads),
306 (lldb.eStopReasonWatchpoint, watchpoint_threads),
307 (lldb.eStopReasonSignal, signal_threads),
308 (lldb.eStopReasonThreadExiting, exiting_threads),
309 (None, other_threads),
311 if not dispatched and list is not None:
312 if thread.GetStopReason() == reason or reason is None:
313 list.append(thread)
314 dispatched = True
317 # ==================================================
318 # Utility functions for setting breakpoints
319 # ==================================================
322 def run_break_set_by_script(
323 test, class_name, extra_options=None, num_expected_locations=1
325 """Set a scripted breakpoint. Check that it got the right number of locations."""
326 test.assertTrue(class_name is not None, "Must pass in a class name.")
327 command = "breakpoint set -P " + class_name
328 if extra_options is not None:
329 command += " " + extra_options
331 break_results = run_break_set_command(test, command)
332 check_breakpoint_result(test, break_results, num_locations=num_expected_locations)
333 return get_bpno_from_match(break_results)
336 def run_break_set_by_file_and_line(
337 test,
338 file_name,
339 line_number,
340 extra_options=None,
341 num_expected_locations=1,
342 loc_exact=False,
343 module_name=None,
345 """Set a breakpoint by file and line, returning the breakpoint number.
347 If extra_options is not None, then we append it to the breakpoint set command.
349 If num_expected_locations is -1, we check that we got AT LEAST one location. If num_expected_locations is -2, we don't
350 check the actual number at all. Otherwise, we check that num_expected_locations equals the number of locations.
352 If loc_exact is true, we check that there is one location, and that location must be at the input file and line number.
355 if file_name is None:
356 command = "breakpoint set -l %d" % (line_number)
357 else:
358 command = 'breakpoint set -f "%s" -l %d' % (file_name, line_number)
360 if module_name:
361 command += " --shlib '%s'" % (module_name)
363 if extra_options:
364 command += " " + extra_options
366 break_results = run_break_set_command(test, command)
368 if num_expected_locations == 1 and loc_exact:
369 check_breakpoint_result(
370 test,
371 break_results,
372 num_locations=num_expected_locations,
373 file_name=file_name,
374 line_number=line_number,
375 module_name=module_name,
377 else:
378 check_breakpoint_result(
379 test, break_results, num_locations=num_expected_locations
382 return get_bpno_from_match(break_results)
385 def run_break_set_by_symbol(
386 test,
387 symbol,
388 extra_options=None,
389 num_expected_locations=-1,
390 sym_exact=False,
391 module_name=None,
393 """Set a breakpoint by symbol name. Common options are the same as run_break_set_by_file_and_line.
395 If sym_exact is true, then the output symbol must match the input exactly, otherwise we do a substring match.
397 command = 'breakpoint set -n "%s"' % (symbol)
399 if module_name:
400 command += " --shlib '%s'" % (module_name)
402 if extra_options:
403 command += " " + extra_options
405 break_results = run_break_set_command(test, command)
407 if num_expected_locations == 1 and sym_exact:
408 check_breakpoint_result(
409 test,
410 break_results,
411 num_locations=num_expected_locations,
412 symbol_name=symbol,
413 module_name=module_name,
415 else:
416 check_breakpoint_result(
417 test, break_results, num_locations=num_expected_locations
420 return get_bpno_from_match(break_results)
423 def run_break_set_by_selector(
424 test, selector, extra_options=None, num_expected_locations=-1, module_name=None
426 """Set a breakpoint by selector. Common options are the same as run_break_set_by_file_and_line."""
428 command = 'breakpoint set -S "%s"' % (selector)
430 if module_name:
431 command += ' --shlib "%s"' % (module_name)
433 if extra_options:
434 command += " " + extra_options
436 break_results = run_break_set_command(test, command)
438 if num_expected_locations == 1:
439 check_breakpoint_result(
440 test,
441 break_results,
442 num_locations=num_expected_locations,
443 symbol_name=selector,
444 symbol_match_exact=False,
445 module_name=module_name,
447 else:
448 check_breakpoint_result(
449 test, break_results, num_locations=num_expected_locations
452 return get_bpno_from_match(break_results)
455 def run_break_set_by_regexp(
456 test, regexp, extra_options=None, num_expected_locations=-1
458 """Set a breakpoint by regular expression match on symbol name. Common options are the same as run_break_set_by_file_and_line."""
460 command = 'breakpoint set -r "%s"' % (regexp)
461 if extra_options:
462 command += " " + extra_options
464 break_results = run_break_set_command(test, command)
466 check_breakpoint_result(test, break_results, num_locations=num_expected_locations)
468 return get_bpno_from_match(break_results)
471 def run_break_set_by_source_regexp(
472 test, regexp, extra_options=None, num_expected_locations=-1
474 """Set a breakpoint by source regular expression. Common options are the same as run_break_set_by_file_and_line."""
475 command = 'breakpoint set -p "%s"' % (regexp)
476 if extra_options:
477 command += " " + extra_options
479 break_results = run_break_set_command(test, command)
481 check_breakpoint_result(test, break_results, num_locations=num_expected_locations)
483 return get_bpno_from_match(break_results)
486 def run_break_set_by_file_colon_line(
487 test,
488 specifier,
489 path,
490 line_number,
491 column_number=0,
492 extra_options=None,
493 num_expected_locations=-1,
495 command = 'breakpoint set -y "%s"' % (specifier)
496 if extra_options:
497 command += " " + extra_options
499 print("About to run: '%s'", command)
500 break_results = run_break_set_command(test, command)
501 check_breakpoint_result(
502 test,
503 break_results,
504 num_locations=num_expected_locations,
505 file_name=path,
506 line_number=line_number,
507 column_number=column_number,
510 return get_bpno_from_match(break_results)
513 def run_break_set_command(test, command):
514 """Run the command passed in - it must be some break set variant - and analyze the result.
515 Returns a dictionary of information gleaned from the command-line results.
516 Will assert if the breakpoint setting fails altogether.
518 Dictionary will contain:
519 bpno - breakpoint of the newly created breakpoint, -1 on error.
520 num_locations - number of locations set for the breakpoint.
522 If there is only one location, the dictionary MAY contain:
523 file - source file name
524 line_no - source line number
525 column - source column number
526 symbol - symbol name
527 inline_symbol - inlined symbol name
528 offset - offset from the original symbol
529 module - module
530 address - address at which the breakpoint was set."""
532 patterns = [
533 r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>[0-9]+) locations\.$",
534 r"^Breakpoint (?P<bpno>[0-9]+): (?P<num_locations>no) locations \(pending\)\.",
535 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]+)$",
536 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]+)$",
538 match_object = test.match(command, patterns)
539 break_results = match_object.groupdict()
541 # We always insert the breakpoint number, setting it to -1 if we couldn't find it
542 # Also, make sure it gets stored as an integer.
543 if not "bpno" in break_results:
544 break_results["bpno"] = -1
545 else:
546 break_results["bpno"] = int(break_results["bpno"])
548 # We always insert the number of locations
549 # If ONE location is set for the breakpoint, then the output doesn't mention locations, but it has to be 1...
550 # We also make sure it is an integer.
552 if not "num_locations" in break_results:
553 num_locations = 1
554 else:
555 num_locations = break_results["num_locations"]
556 if num_locations == "no":
557 num_locations = 0
558 else:
559 num_locations = int(break_results["num_locations"])
561 break_results["num_locations"] = num_locations
563 if "line_no" in break_results:
564 break_results["line_no"] = int(break_results["line_no"])
566 return break_results
569 def get_bpno_from_match(break_results):
570 return int(break_results["bpno"])
573 def check_breakpoint_result(
574 test,
575 break_results,
576 file_name=None,
577 line_number=-1,
578 column_number=0,
579 symbol_name=None,
580 symbol_match_exact=True,
581 module_name=None,
582 offset=-1,
583 num_locations=-1,
585 out_num_locations = break_results["num_locations"]
587 if num_locations == -1:
588 test.assertTrue(
589 out_num_locations > 0, "Expecting one or more locations, got none."
591 elif num_locations != -2:
592 test.assertTrue(
593 num_locations == out_num_locations,
594 "Expecting %d locations, got %d." % (num_locations, out_num_locations),
597 if file_name:
598 out_file_name = ""
599 if "file" in break_results:
600 out_file_name = break_results["file"]
601 test.assertTrue(
602 file_name.endswith(out_file_name),
603 "Breakpoint file name '%s' doesn't match resultant name '%s'."
604 % (file_name, out_file_name),
607 if line_number != -1:
608 out_line_number = -1
609 if "line_no" in break_results:
610 out_line_number = break_results["line_no"]
612 test.assertTrue(
613 line_number == out_line_number,
614 "Breakpoint line number %s doesn't match resultant line %s."
615 % (line_number, out_line_number),
618 if column_number != 0:
619 out_column_number = 0
620 if "column" in break_results:
621 out_column_number = break_results["column"]
623 test.assertTrue(
624 column_number == out_column_number,
625 "Breakpoint column number %s doesn't match resultant column %s."
626 % (column_number, out_column_number),
629 if symbol_name:
630 out_symbol_name = ""
631 # Look first for the inlined symbol name, otherwise use the symbol
632 # name:
633 if "inline_symbol" in break_results and break_results["inline_symbol"]:
634 out_symbol_name = break_results["inline_symbol"]
635 elif "symbol" in break_results:
636 out_symbol_name = break_results["symbol"]
638 if symbol_match_exact:
639 test.assertTrue(
640 symbol_name == out_symbol_name,
641 "Symbol name '%s' doesn't match resultant symbol '%s'."
642 % (symbol_name, out_symbol_name),
644 else:
645 test.assertTrue(
646 out_symbol_name.find(symbol_name) != -1,
647 "Symbol name '%s' isn't in resultant symbol '%s'."
648 % (symbol_name, out_symbol_name),
651 if module_name:
652 out_module_name = None
653 if "module" in break_results:
654 out_module_name = break_results["module"]
656 test.assertTrue(
657 module_name.find(out_module_name) != -1,
658 "Symbol module name '%s' isn't in expected module name '%s'."
659 % (out_module_name, module_name),
663 def check_breakpoint(
664 test,
665 bpno,
666 expected_locations=None,
667 expected_resolved_count=None,
668 expected_hit_count=None,
669 location_id=None,
670 expected_location_resolved=True,
671 expected_location_hit_count=None,
674 Test breakpoint or breakpoint location.
675 Breakpoint resolved count is always checked. If not specified the assumption is that all locations
676 should be resolved.
677 To test a breakpoint location, breakpoint number (bpno) and location_id must be set. In this case
678 the resolved count for a breakpoint is not tested by default. The location is expected to be resolved,
679 unless expected_location_resolved is set to False.
680 test - test context
681 bpno - breakpoint number to test
682 expected_locations - expected number of locations for this breakpoint. If 'None' this parameter is not tested.
683 expected_resolved_count - expected resolved locations number for the breakpoint. If 'None' - all locations should be resolved.
684 expected_hit_count - expected hit count for this breakpoint. If 'None' this parameter is not tested.
685 location_id - If not 'None' sets the location ID for the breakpoint to test.
686 expected_location_resolved - Extected resolved status for the location_id (True/False). Default - True.
687 expected_location_hit_count - Expected hit count for the breakpoint at location_id. Must be set if the location_id parameter is set.
690 if isinstance(test.target, lldb.SBTarget):
691 target = test.target
692 else:
693 target = test.target()
694 bkpt = target.FindBreakpointByID(bpno)
696 test.assertTrue(bkpt.IsValid(), "Breakpoint is not valid.")
698 if expected_locations is not None:
699 test.assertEqual(expected_locations, bkpt.GetNumLocations())
701 if expected_resolved_count is not None:
702 test.assertEqual(expected_resolved_count, bkpt.GetNumResolvedLocations())
703 else:
704 expected_resolved_count = bkpt.GetNumLocations()
705 if location_id is None:
706 test.assertEqual(expected_resolved_count, bkpt.GetNumResolvedLocations())
708 if expected_hit_count is not None:
709 test.assertEqual(expected_hit_count, bkpt.GetHitCount())
711 if location_id is not None:
712 loc_bkpt = bkpt.FindLocationByID(location_id)
713 test.assertTrue(loc_bkpt.IsValid(), "Breakpoint location is not valid.")
714 test.assertEqual(loc_bkpt.IsResolved(), expected_location_resolved)
715 if expected_location_hit_count is not None:
716 test.assertEqual(expected_location_hit_count, loc_bkpt.GetHitCount())
719 # ==================================================
720 # Utility functions related to Threads and Processes
721 # ==================================================
724 def get_stopped_threads(process, reason):
725 """Returns the thread(s) with the specified stop reason in a list.
727 The list can be empty if no such thread exists.
729 threads = []
730 for t in process:
731 if t.GetStopReason() == reason:
732 threads.append(t)
733 return threads
736 def get_stopped_thread(process, reason):
737 """A convenience function which returns the first thread with the given stop
738 reason or None.
740 Example usages:
742 1. Get the stopped thread due to a breakpoint condition
745 from lldbutil import get_stopped_thread
746 thread = get_stopped_thread(process, lldb.eStopReasonPlanComplete)
747 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint condition")
750 2. Get the thread stopped due to a breakpoint
753 from lldbutil import get_stopped_thread
754 thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
755 self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint")
759 threads = get_stopped_threads(process, reason)
760 if len(threads) == 0:
761 return None
762 return threads[0]
765 def get_threads_stopped_at_breakpoint_id(process, bpid):
766 """For a stopped process returns the thread stopped at the breakpoint passed in bkpt"""
767 stopped_threads = []
768 threads = []
770 stopped_threads = get_stopped_threads(process, lldb.eStopReasonBreakpoint)
772 if len(stopped_threads) == 0:
773 return threads
775 for thread in stopped_threads:
776 # Make sure we've hit our breakpoint...
777 break_id = thread.GetStopReasonDataAtIndex(0)
778 if break_id == bpid:
779 threads.append(thread)
781 return threads
784 def get_threads_stopped_at_breakpoint(process, bkpt):
785 return get_threads_stopped_at_breakpoint_id(process, bkpt.GetID())
788 def get_one_thread_stopped_at_breakpoint_id(process, bpid, require_exactly_one=True):
789 threads = get_threads_stopped_at_breakpoint_id(process, bpid)
790 if len(threads) == 0:
791 return None
792 if require_exactly_one and len(threads) != 1:
793 return None
795 return threads[0]
798 def get_one_thread_stopped_at_breakpoint(process, bkpt, require_exactly_one=True):
799 return get_one_thread_stopped_at_breakpoint_id(
800 process, bkpt.GetID(), require_exactly_one
804 def is_thread_crashed(test, thread):
805 """In the test suite we dereference a null pointer to simulate a crash. The way this is
806 reported depends on the platform."""
807 if test.platformIsDarwin():
808 return (
809 thread.GetStopReason() == lldb.eStopReasonException
810 and "EXC_BAD_ACCESS" in thread.GetStopDescription(100)
812 elif test.getPlatform() == "linux":
813 return (
814 thread.GetStopReason() == lldb.eStopReasonSignal
815 and thread.GetStopReasonDataAtIndex(0)
816 == thread.GetProcess().GetUnixSignals().GetSignalNumberFromName("SIGSEGV")
818 elif test.getPlatform() == "windows":
819 return "Exception 0xc0000005" in thread.GetStopDescription(200)
820 else:
821 return "invalid address" in thread.GetStopDescription(100)
824 def get_crashed_threads(test, process):
825 threads = []
826 if process.GetState() != lldb.eStateStopped:
827 return threads
828 for thread in process:
829 if is_thread_crashed(test, thread):
830 threads.append(thread)
831 return threads
834 # Helper functions for run_to_{source,name}_breakpoint:
837 def run_to_breakpoint_make_target(test, exe_name="a.out", in_cwd=True):
838 exe = test.getBuildArtifact(exe_name) if in_cwd else exe_name
840 # Create the target
841 target = test.dbg.CreateTarget(exe)
842 test.assertTrue(target, "Target: %s is not valid." % (exe_name))
844 # Set environment variables for the inferior.
845 if lldbtest_config.inferior_env:
846 test.runCmd(
847 "settings set target.env-vars {}".format(lldbtest_config.inferior_env)
850 return target
853 def run_to_breakpoint_do_run(
854 test, target, bkpt, launch_info=None, only_one_thread=True, extra_images=None
856 # Launch the process, and do not stop at the entry point.
857 if not launch_info:
858 launch_info = target.GetLaunchInfo()
859 launch_info.SetWorkingDirectory(test.get_process_working_directory())
861 if extra_images:
862 environ = test.registerSharedLibrariesWithTarget(target, extra_images)
863 launch_info.SetEnvironmentEntries(environ, True)
865 error = lldb.SBError()
866 process = target.Launch(launch_info, error)
868 # Unfortunate workaround for the iPhone simulator.
869 retry = SIMULATOR_RETRY
870 while (
871 retry
872 and error.Fail()
873 and error.GetCString()
874 and "Unable to boot the Simulator" in error.GetCString()
876 retry -= 1
877 print("** Simulator is unresponsive. Retrying %d more time(s)" % retry)
878 import time
880 time.sleep(60)
881 error = lldb.SBError()
882 process = target.Launch(launch_info, error)
884 test.assertTrue(
885 process,
886 "Could not create a valid process for %s: %s"
887 % (target.GetExecutable().GetFilename(), error.GetCString()),
889 test.assertFalse(error.Fail(), "Process launch failed: %s" % (error.GetCString()))
891 def processStateInfo(process):
892 info = "state: {}".format(state_type_to_str(process.state))
893 if process.state == lldb.eStateExited:
894 info += ", exit code: {}".format(process.GetExitStatus())
895 if process.exit_description:
896 info += ", exit description: '{}'".format(process.exit_description)
897 stdout = process.GetSTDOUT(999)
898 if stdout:
899 info += ", stdout: '{}'".format(stdout)
900 stderr = process.GetSTDERR(999)
901 if stderr:
902 info += ", stderr: '{}'".format(stderr)
903 return info
905 if process.state != lldb.eStateStopped:
906 test.fail(
907 "Test process is not stopped at breakpoint: {}".format(
908 processStateInfo(process)
912 # Frame #0 should be at our breakpoint.
913 threads = get_threads_stopped_at_breakpoint(process, bkpt)
915 num_threads = len(threads)
916 if only_one_thread:
917 test.assertEqual(
918 num_threads,
920 "Expected 1 thread to stop at breakpoint, %d did." % (num_threads),
922 else:
923 test.assertGreater(num_threads, 0, "No threads stopped at breakpoint")
925 thread = threads[0]
926 return (target, process, thread, bkpt)
929 def run_to_name_breakpoint(
930 test,
931 bkpt_name,
932 launch_info=None,
933 exe_name="a.out",
934 bkpt_module=None,
935 in_cwd=True,
936 only_one_thread=True,
937 extra_images=None,
939 """Start up a target, using exe_name as the executable, and run it to
940 a breakpoint set by name on bkpt_name restricted to bkpt_module.
942 If you want to pass in launch arguments or environment
943 variables, you can optionally pass in an SBLaunchInfo. If you
944 do that, remember to set the working directory as well.
946 If your executable isn't called a.out, you can pass that in.
947 And if your executable isn't in the CWD, pass in the absolute
948 path to the executable in exe_name, and set in_cwd to False.
950 If you need to restrict the breakpoint to a particular module,
951 pass the module name (a string not a FileSpec) in bkpt_module. If
952 nothing is passed in setting will be unrestricted.
954 If the target isn't valid, the breakpoint isn't found, or hit, the
955 function will cause a testsuite failure.
957 If successful it returns a tuple with the target process and
958 thread that hit the breakpoint, and the breakpoint that we set
959 for you.
961 If only_one_thread is true, we require that there be only one
962 thread stopped at the breakpoint. Otherwise we only require one
963 or more threads stop there. If there are more than one, we return
964 the first thread that stopped.
967 target = run_to_breakpoint_make_target(test, exe_name, in_cwd)
969 breakpoint = target.BreakpointCreateByName(bkpt_name, bkpt_module)
971 test.assertTrue(
972 breakpoint.GetNumLocations() > 0,
973 "No locations found for name breakpoint: '%s'." % (bkpt_name),
975 return run_to_breakpoint_do_run(
976 test, target, breakpoint, launch_info, only_one_thread, extra_images
980 def run_to_source_breakpoint(
981 test,
982 bkpt_pattern,
983 source_spec,
984 launch_info=None,
985 exe_name="a.out",
986 bkpt_module=None,
987 in_cwd=True,
988 only_one_thread=True,
989 extra_images=None,
990 has_locations_before_run=True,
992 """Start up a target, using exe_name as the executable, and run it to
993 a breakpoint set by source regex bkpt_pattern.
995 The rest of the behavior is the same as run_to_name_breakpoint.
998 target = run_to_breakpoint_make_target(test, exe_name, in_cwd)
999 # Set the breakpoints
1000 breakpoint = target.BreakpointCreateBySourceRegex(
1001 bkpt_pattern, source_spec, bkpt_module
1003 if has_locations_before_run:
1004 test.assertTrue(
1005 breakpoint.GetNumLocations() > 0,
1006 'No locations found for source breakpoint: "%s", file: "%s", dir: "%s"'
1007 % (bkpt_pattern, source_spec.GetFilename(), source_spec.GetDirectory()),
1009 return run_to_breakpoint_do_run(
1010 test, target, breakpoint, launch_info, only_one_thread, extra_images
1014 def run_to_line_breakpoint(
1015 test,
1016 source_spec,
1017 line_number,
1018 column=0,
1019 launch_info=None,
1020 exe_name="a.out",
1021 bkpt_module=None,
1022 in_cwd=True,
1023 only_one_thread=True,
1024 extra_images=None,
1026 """Start up a target, using exe_name as the executable, and run it to
1027 a breakpoint set by (source_spec, line_number(, column)).
1029 The rest of the behavior is the same as run_to_name_breakpoint.
1032 target = run_to_breakpoint_make_target(test, exe_name, in_cwd)
1033 # Set the breakpoints
1034 breakpoint = target.BreakpointCreateByLocation(
1035 source_spec, line_number, column, 0, lldb.SBFileSpecList()
1037 test.assertTrue(
1038 breakpoint.GetNumLocations() > 0,
1039 'No locations found for line breakpoint: "%s:%d(:%d)", dir: "%s"'
1040 % (source_spec.GetFilename(), line_number, column, source_spec.GetDirectory()),
1042 return run_to_breakpoint_do_run(
1043 test, target, breakpoint, launch_info, only_one_thread, extra_images
1047 def continue_to_breakpoint(process, bkpt):
1048 """Continues the process, if it stops, returns the threads stopped at bkpt; otherwise, returns None"""
1049 process.Continue()
1050 if process.GetState() != lldb.eStateStopped:
1051 return None
1052 else:
1053 return get_threads_stopped_at_breakpoint(process, bkpt)
1056 def continue_to_source_breakpoint(test, process, bkpt_pattern, source_spec):
1058 Sets a breakpoint set by source regex bkpt_pattern, continues the process, and deletes the breakpoint again.
1059 Otherwise the same as `continue_to_breakpoint`
1061 breakpoint = process.target.BreakpointCreateBySourceRegex(
1062 bkpt_pattern, source_spec, None
1064 test.assertTrue(
1065 breakpoint.GetNumLocations() > 0,
1066 'No locations found for source breakpoint: "%s", file: "%s", dir: "%s"'
1067 % (bkpt_pattern, source_spec.GetFilename(), source_spec.GetDirectory()),
1069 stopped_threads = continue_to_breakpoint(process, breakpoint)
1070 process.target.BreakpointDelete(breakpoint.GetID())
1071 return stopped_threads
1074 def get_caller_symbol(thread):
1076 Returns the symbol name for the call site of the leaf function.
1078 depth = thread.GetNumFrames()
1079 if depth <= 1:
1080 return None
1081 caller = thread.GetFrameAtIndex(1).GetSymbol()
1082 if caller:
1083 return caller.GetName()
1084 else:
1085 return None
1088 def get_function_names(thread):
1090 Returns a sequence of function names from the stack frames of this thread.
1093 def GetFuncName(i):
1094 return thread.GetFrameAtIndex(i).GetFunctionName()
1096 return list(map(GetFuncName, list(range(thread.GetNumFrames()))))
1099 def get_symbol_names(thread):
1101 Returns a sequence of symbols for this thread.
1104 def GetSymbol(i):
1105 return thread.GetFrameAtIndex(i).GetSymbol().GetName()
1107 return list(map(GetSymbol, list(range(thread.GetNumFrames()))))
1110 def get_pc_addresses(thread):
1112 Returns a sequence of pc addresses for this thread.
1115 def GetPCAddress(i):
1116 return thread.GetFrameAtIndex(i).GetPCAddress()
1118 return list(map(GetPCAddress, list(range(thread.GetNumFrames()))))
1121 def get_filenames(thread):
1123 Returns a sequence of file names from the stack frames of this thread.
1126 def GetFilename(i):
1127 return thread.GetFrameAtIndex(i).GetLineEntry().GetFileSpec().GetFilename()
1129 return list(map(GetFilename, list(range(thread.GetNumFrames()))))
1132 def get_line_numbers(thread):
1134 Returns a sequence of line numbers from the stack frames of this thread.
1137 def GetLineNumber(i):
1138 return thread.GetFrameAtIndex(i).GetLineEntry().GetLine()
1140 return list(map(GetLineNumber, list(range(thread.GetNumFrames()))))
1143 def get_module_names(thread):
1145 Returns a sequence of module names from the stack frames of this thread.
1148 def GetModuleName(i):
1149 return thread.GetFrameAtIndex(i).GetModule().GetFileSpec().GetFilename()
1151 return list(map(GetModuleName, list(range(thread.GetNumFrames()))))
1154 def get_stack_frames(thread):
1156 Returns a sequence of stack frames for this thread.
1159 def GetStackFrame(i):
1160 return thread.GetFrameAtIndex(i)
1162 return list(map(GetStackFrame, list(range(thread.GetNumFrames()))))
1165 def print_stacktrace(thread, string_buffer=False):
1166 """Prints a simple stack trace of this thread."""
1168 output = io.StringIO() if string_buffer else sys.stdout
1169 target = thread.GetProcess().GetTarget()
1171 depth = thread.GetNumFrames()
1173 mods = get_module_names(thread)
1174 funcs = get_function_names(thread)
1175 symbols = get_symbol_names(thread)
1176 files = get_filenames(thread)
1177 lines = get_line_numbers(thread)
1178 addrs = get_pc_addresses(thread)
1180 if thread.GetStopReason() != lldb.eStopReasonInvalid:
1181 desc = "stop reason=" + stop_reason_to_str(thread.GetStopReason())
1182 else:
1183 desc = ""
1184 print(
1185 "Stack trace for thread id={0:#x} name={1} queue={2} ".format(
1186 thread.GetThreadID(), thread.GetName(), thread.GetQueueName()
1188 + desc,
1189 file=output,
1192 for i in range(depth):
1193 frame = thread.GetFrameAtIndex(i)
1194 function = frame.GetFunction()
1196 load_addr = addrs[i].GetLoadAddress(target)
1197 if not function:
1198 file_addr = addrs[i].GetFileAddress()
1199 start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress()
1200 symbol_offset = file_addr - start_addr
1201 print(
1202 " frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}".format(
1203 num=i,
1204 addr=load_addr,
1205 mod=mods[i],
1206 symbol=symbols[i],
1207 offset=symbol_offset,
1209 file=output,
1211 else:
1212 print(
1213 " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format(
1214 num=i,
1215 addr=load_addr,
1216 mod=mods[i],
1217 func="%s [inlined]" % funcs[i] if frame.IsInlined() else funcs[i],
1218 file=files[i],
1219 line=lines[i],
1220 args=get_args_as_string(frame, showFuncName=False)
1221 if not frame.IsInlined()
1222 else "()",
1224 file=output,
1227 if string_buffer:
1228 return output.getvalue()
1231 def print_stacktraces(process, string_buffer=False):
1232 """Prints the stack traces of all the threads."""
1234 output = io.StringIO() if string_buffer else sys.stdout
1236 print("Stack traces for " + str(process), file=output)
1238 for thread in process:
1239 print(print_stacktrace(thread, string_buffer=True), file=output)
1241 if string_buffer:
1242 return output.getvalue()
1245 def expect_state_changes(test, listener, process, states, timeout=30):
1246 """Listens for state changed events on the listener and makes sure they match what we
1247 expect. Stop-and-restart events (where GetRestartedFromEvent() returns true) are ignored.
1250 for expected_state in states:
1252 def get_next_event():
1253 event = lldb.SBEvent()
1254 if not listener.WaitForEventForBroadcasterWithType(
1255 timeout,
1256 process.GetBroadcaster(),
1257 lldb.SBProcess.eBroadcastBitStateChanged,
1258 event,
1260 test.fail(
1261 "Timed out while waiting for a transition to state %s"
1262 % lldb.SBDebugger.StateAsCString(expected_state)
1264 return event
1266 event = get_next_event()
1267 while lldb.SBProcess.GetStateFromEvent(
1268 event
1269 ) == lldb.eStateStopped and lldb.SBProcess.GetRestartedFromEvent(event):
1270 # Ignore restarted event and the subsequent running event.
1271 event = get_next_event()
1272 test.assertEqual(
1273 lldb.SBProcess.GetStateFromEvent(event),
1274 lldb.eStateRunning,
1275 "Restarted event followed by a running event",
1277 event = get_next_event()
1279 test.assertEqual(lldb.SBProcess.GetStateFromEvent(event), expected_state)
1282 def start_listening_from(broadcaster, event_mask):
1283 """Creates a listener for a specific event mask and add it to the source broadcaster."""
1285 listener = lldb.SBListener("lldb.test.listener")
1286 broadcaster.AddListener(listener, event_mask)
1287 return listener
1290 def fetch_next_event(test, listener, broadcaster, match_class=False, timeout=10):
1291 """Fetch one event from the listener and return it if it matches the provided broadcaster.
1292 If `match_class` is set to True, this will match an event with an entire broadcaster class.
1293 Fails otherwise."""
1295 event = lldb.SBEvent()
1297 if listener.WaitForEvent(timeout, event):
1298 if match_class:
1299 if event.GetBroadcasterClass() == broadcaster:
1300 return event
1301 else:
1302 if event.BroadcasterMatchesRef(broadcaster):
1303 return event
1305 stream = lldb.SBStream()
1306 event.GetDescription(stream)
1307 test.fail(
1308 "received event '%s' from unexpected broadcaster '%s'."
1309 % (stream.GetData(), event.GetBroadcaster().GetName())
1312 test.fail("couldn't fetch an event before reaching the timeout.")
1315 # ===================================
1316 # Utility functions related to Frames
1317 # ===================================
1320 def get_parent_frame(frame):
1322 Returns the parent frame of the input frame object; None if not available.
1324 thread = frame.GetThread()
1325 parent_found = False
1326 for f in thread:
1327 if parent_found:
1328 return f
1329 if f.GetFrameID() == frame.GetFrameID():
1330 parent_found = True
1332 # If we reach here, no parent has been found, return None.
1333 return None
1336 def get_args_as_string(frame, showFuncName=True):
1338 Returns the args of the input frame object as a string.
1340 # arguments => True
1341 # locals => False
1342 # statics => False
1343 # in_scope_only => True
1344 vars = frame.GetVariables(True, False, False, True) # type of SBValueList
1345 args = [] # list of strings
1346 for var in vars:
1347 args.append("(%s)%s=%s" % (var.GetTypeName(), var.GetName(), var.GetValue()))
1348 if frame.GetFunction():
1349 name = frame.GetFunction().GetName()
1350 elif frame.GetSymbol():
1351 name = frame.GetSymbol().GetName()
1352 else:
1353 name = ""
1354 if showFuncName:
1355 return "%s(%s)" % (name, ", ".join(args))
1356 else:
1357 return "(%s)" % (", ".join(args))
1360 def print_registers(frame, string_buffer=False):
1361 """Prints all the register sets of the frame."""
1363 output = io.StringIO() if string_buffer else sys.stdout
1365 print("Register sets for " + str(frame), file=output)
1367 registerSet = frame.GetRegisters() # Return type of SBValueList.
1368 print(
1369 "Frame registers (size of register set = %d):" % registerSet.GetSize(),
1370 file=output,
1372 for value in registerSet:
1373 # print(value, file=output)
1374 print(
1375 "%s (number of children = %d):" % (value.GetName(), value.GetNumChildren()),
1376 file=output,
1378 for child in value:
1379 print(
1380 "Name: %s, Value: %s" % (child.GetName(), child.GetValue()), file=output
1383 if string_buffer:
1384 return output.getvalue()
1387 def get_registers(frame, kind):
1388 """Returns the registers given the frame and the kind of registers desired.
1390 Returns None if there's no such kind.
1392 registerSet = frame.GetRegisters() # Return type of SBValueList.
1393 for value in registerSet:
1394 if kind.lower() in value.GetName().lower():
1395 return value
1397 return None
1400 def get_GPRs(frame):
1401 """Returns the general purpose registers of the frame as an SBValue.
1403 The returned SBValue object is iterable. An example:
1405 from lldbutil import get_GPRs
1406 regs = get_GPRs(frame)
1407 for reg in regs:
1408 print("%s => %s" % (reg.GetName(), reg.GetValue()))
1411 return get_registers(frame, "general purpose")
1414 def get_FPRs(frame):
1415 """Returns the floating point registers of the frame as an SBValue.
1417 The returned SBValue object is iterable. An example:
1419 from lldbutil import get_FPRs
1420 regs = get_FPRs(frame)
1421 for reg in regs:
1422 print("%s => %s" % (reg.GetName(), reg.GetValue()))
1425 return get_registers(frame, "floating point")
1428 def get_ESRs(frame):
1429 """Returns the exception state registers of the frame as an SBValue.
1431 The returned SBValue object is iterable. An example:
1433 from lldbutil import get_ESRs
1434 regs = get_ESRs(frame)
1435 for reg in regs:
1436 print("%s => %s" % (reg.GetName(), reg.GetValue()))
1439 return get_registers(frame, "exception state")
1442 # ======================================
1443 # Utility classes/functions for SBValues
1444 # ======================================
1447 class BasicFormatter(object):
1448 """The basic formatter inspects the value object and prints the value."""
1450 def format(self, value, buffer=None, indent=0):
1451 if not buffer:
1452 output = io.StringIO()
1453 else:
1454 output = buffer
1455 # If there is a summary, it suffices.
1456 val = value.GetSummary()
1457 # Otherwise, get the value.
1458 if val is None:
1459 val = value.GetValue()
1460 if val is None and value.GetNumChildren() > 0:
1461 val = "%s (location)" % value.GetLocation()
1462 print(
1463 "{indentation}({type}) {name} = {value}".format(
1464 indentation=" " * indent,
1465 type=value.GetTypeName(),
1466 name=value.GetName(),
1467 value=val,
1469 file=output,
1471 return output.getvalue()
1474 class ChildVisitingFormatter(BasicFormatter):
1475 """The child visiting formatter prints the value and its immediate children.
1477 The constructor takes a keyword arg: indent_child, which defaults to 2.
1480 def __init__(self, indent_child=2):
1481 """Default indentation of 2 SPC's for the children."""
1482 self.cindent = indent_child
1484 def format(self, value, buffer=None):
1485 if not buffer:
1486 output = io.StringIO()
1487 else:
1488 output = buffer
1490 BasicFormatter.format(self, value, buffer=output)
1491 for child in value:
1492 BasicFormatter.format(self, child, buffer=output, indent=self.cindent)
1494 return output.getvalue()
1497 class RecursiveDecentFormatter(BasicFormatter):
1498 """The recursive decent formatter prints the value and the decendents.
1500 The constructor takes two keyword args: indent_level, which defaults to 0,
1501 and indent_child, which defaults to 2. The current indentation level is
1502 determined by indent_level, while the immediate children has an additional
1503 indentation by inden_child.
1506 def __init__(self, indent_level=0, indent_child=2):
1507 self.lindent = indent_level
1508 self.cindent = indent_child
1510 def format(self, value, buffer=None):
1511 if not buffer:
1512 output = io.StringIO()
1513 else:
1514 output = buffer
1516 BasicFormatter.format(self, value, buffer=output, indent=self.lindent)
1517 new_indent = self.lindent + self.cindent
1518 for child in value:
1519 if child.GetSummary() is not None:
1520 BasicFormatter.format(self, child, buffer=output, indent=new_indent)
1521 else:
1522 if child.GetNumChildren() > 0:
1523 rdf = RecursiveDecentFormatter(indent_level=new_indent)
1524 rdf.format(child, buffer=output)
1525 else:
1526 BasicFormatter.format(self, child, buffer=output, indent=new_indent)
1528 return output.getvalue()
1531 # ===========================================================
1532 # Utility functions for path manipulation on remote platforms
1533 # ===========================================================
1536 def join_remote_paths(*paths):
1537 # TODO: update with actual platform name for remote windows once it exists
1538 if lldb.remote_platform.GetName() == "remote-windows":
1539 return os.path.join(*paths).replace(os.path.sep, "\\")
1540 return os.path.join(*paths).replace(os.path.sep, "/")
1543 def append_to_process_working_directory(test, *paths):
1544 remote = lldb.remote_platform
1545 if remote:
1546 return join_remote_paths(remote.GetWorkingDirectory(), *paths)
1547 return os.path.join(test.getBuildDir(), *paths)
1550 # ==================================================
1551 # Utility functions to get the correct signal number
1552 # ==================================================
1554 import signal
1557 def get_signal_number(signal_name):
1558 platform = lldb.remote_platform
1559 if platform and platform.IsValid():
1560 signals = platform.GetUnixSignals()
1561 if signals.IsValid():
1562 signal_number = signals.GetSignalNumberFromName(signal_name)
1563 if signal_number > 0:
1564 return signal_number
1565 # No remote platform; fall back to using local python signals.
1566 return getattr(signal, signal_name)
1569 def get_actions_for_signal(
1570 testcase, signal_name, from_target=False, expected_absent=False
1572 """Returns a triple of (pass, stop, notify)"""
1573 return_obj = lldb.SBCommandReturnObject()
1574 command = "process handle {0}".format(signal_name)
1575 if from_target:
1576 command += " -t"
1577 testcase.dbg.GetCommandInterpreter().HandleCommand(command, return_obj)
1578 match = re.match(
1579 "NAME *PASS *STOP *NOTIFY.*(false|true|not set) *(false|true|not set) *(false|true|not set)",
1580 return_obj.GetOutput(),
1581 re.IGNORECASE | re.DOTALL,
1583 if match and expected_absent:
1584 testcase.fail('Signal "{0}" was supposed to be absent'.format(signal_name))
1585 if not match:
1586 if expected_absent:
1587 return (None, None, None)
1588 testcase.fail("Unable to retrieve default signal disposition.")
1589 return (match.group(1), match.group(2), match.group(3))
1592 def set_actions_for_signal(
1593 testcase, signal_name, pass_action, stop_action, notify_action, expect_success=True
1595 return_obj = lldb.SBCommandReturnObject()
1596 command = "process handle {0}".format(signal_name)
1597 if pass_action != None:
1598 command += " -p {0}".format(pass_action)
1599 if stop_action != None:
1600 command += " -s {0}".format(stop_action)
1601 if notify_action != None:
1602 command += " -n {0}".format(notify_action)
1604 testcase.dbg.GetCommandInterpreter().HandleCommand(command, return_obj)
1605 testcase.assertEqual(
1606 expect_success,
1607 return_obj.Succeeded(),
1608 "Setting signal handling for {0} worked as expected".format(signal_name),
1612 class PrintableRegex(object):
1613 def __init__(self, text):
1614 self.regex = re.compile(text)
1615 self.text = text
1617 def match(self, str):
1618 return self.regex.match(str)
1620 def __str__(self):
1621 return "%s" % (self.text)
1623 def __repr__(self):
1624 return "re.compile(%s) -> %s" % (self.text, self.regex)
1627 def skip_if_callable(test, mycallable, reason):
1628 if callable(mycallable):
1629 if mycallable(test):
1630 test.skipTest(reason)
1631 return True
1632 return False
1635 def skip_if_library_missing(test, target, library):
1636 def find_library(target, library):
1637 for module in target.modules:
1638 filename = module.file.GetFilename()
1639 if isinstance(library, str):
1640 if library == filename:
1641 return False
1642 elif hasattr(library, "match"):
1643 if library.match(filename):
1644 return False
1645 return True
1647 def find_library_callable(test):
1648 return find_library(target, library)
1650 return skip_if_callable(
1651 test,
1652 find_library_callable,
1653 "could not find library matching '%s' in target %s" % (library, target),
1657 def read_file_on_target(test, remote):
1658 if lldb.remote_platform:
1659 local = test.getBuildArtifact("file_from_target")
1660 error = lldb.remote_platform.Get(
1661 lldb.SBFileSpec(remote, False), lldb.SBFileSpec(local, True)
1663 test.assertTrue(
1664 error.Success(), "Reading file {0} failed: {1}".format(remote, error)
1666 else:
1667 local = remote
1668 with open(local, "r") as f:
1669 return f.read()
1672 def read_file_from_process_wd(test, name):
1673 path = append_to_process_working_directory(test, name)
1674 return read_file_on_target(test, path)
1677 def wait_for_file_on_target(testcase, file_path, max_attempts=6):
1678 for i in range(max_attempts):
1679 err, retcode, msg = testcase.run_platform_command("ls %s" % file_path)
1680 if err.Success() and retcode == 0:
1681 break
1682 if i < max_attempts:
1683 # Exponential backoff!
1684 import time
1686 time.sleep(pow(2, i) * 0.25)
1687 else:
1688 testcase.fail(
1689 "File %s not found even after %d attempts." % (file_path, max_attempts)
1692 return read_file_on_target(testcase, file_path)
1695 def packetlog_get_process_info(log):
1696 """parse a gdb-remote packet log file and extract the response to qProcessInfo"""
1697 process_info = dict()
1698 with open(log, "r") as logfile:
1699 process_info_ostype = None
1700 expect_process_info_response = False
1701 for line in logfile:
1702 if expect_process_info_response:
1703 for pair in line.split(";"):
1704 keyval = pair.split(":")
1705 if len(keyval) == 2:
1706 process_info[keyval[0]] = keyval[1]
1707 break
1708 if "send packet: $qProcessInfo#" in line:
1709 expect_process_info_response = True
1710 return process_info
1713 def packetlog_get_dylib_info(log):
1714 """parse a gdb-remote packet log file and extract the *last* complete
1715 (=> fetch_all_solibs=true) response to jGetLoadedDynamicLibrariesInfos"""
1716 import json
1718 dylib_info = None
1719 with open(log, "r") as logfile:
1720 dylib_info = None
1721 expect_dylib_info_response = False
1722 for line in logfile:
1723 if expect_dylib_info_response:
1724 while line[0] != "$":
1725 line = line[1:]
1726 line = line[1:]
1727 # Unescape '}'.
1728 dylib_info = json.loads(line.replace("}]", "}")[:-4])
1729 expect_dylib_info_response = False
1730 if (
1731 'send packet: $jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true}'
1732 in line
1734 expect_dylib_info_response = True
1736 return dylib_info