1# This Source Code Form is subject to the terms of the Mozilla Public 2# License, v. 2.0. If a copy of the MPL was not distributed with this file, 3# You can obtain one at http://mozilla.org/MPL/2.0/. 4 5# flake8: noqa: F821 6 7import gdb 8import re 9import sys 10import traceback 11 12# testlibdir is set on the GDB command line, via --eval-command python testlibdir=... 13sys.path[0:0] = [testlibdir] 14 15active_fragment = None 16 17# Run the C++ fragment named |fragment|, stopping on entry to |function| 18# ('breakpoint', by default) and then select the calling frame. 19 20 21def run_fragment(fragment, function="gdb-tests.cpp:breakpoint"): 22 # Arrange to stop at a reasonable place in the test program. 23 bp = gdb.Breakpoint(function) 24 try: 25 gdb.execute("run %s" % (fragment,)) 26 # Check that we did indeed stop by hitting the breakpoint we set. 27 assert bp.hit_count == 1 28 finally: 29 bp.delete() 30 gdb.execute("frame 1") 31 32 global active_fragment 33 active_fragment = fragment 34 35 36# Assert that |actual| is equal to |expected|; if not, complain in a helpful way. 37 38 39def assert_eq(actual, expected): 40 if actual != expected: 41 raise AssertionError( 42 """Unexpected result: 43expected: %r 44actual: %r""" 45 % (expected, actual) 46 ) 47 48 49# Assert that |expected| regex matches |actual| result; if not, complain in a helpful way. 50 51 52def assert_match(actual, expected): 53 if re.match(expected, actual, re.MULTILINE) is None: 54 raise AssertionError( 55 """Unexpected result: 56expected pattern: %r 57actual: %r""" 58 % (expected, actual) 59 ) 60 61 62# Assert that |value|'s pretty-printed form is |form|. If |value| is a 63# string, then evaluate it with gdb.parse_and_eval to produce a value. 64 65 66def assert_pretty(value, form): 67 if isinstance(value, str): 68 value = gdb.parse_and_eval(value) 69 assert_eq(str(value), form) 70 71 72# Assert that |value|'s pretty-printed form match the pattern |pattern|. If 73# |value| is a string, then evaluate it with gdb.parse_and_eval to produce a 74# value. 75 76 77def assert_regexp_pretty(value, form): 78 if isinstance(value, str): 79 value = gdb.parse_and_eval(value) 80 assert_match(str(value), form) 81 82 83# Check that the list of registered pretty-printers includes one named 84# |printer|, with a subprinter named |subprinter|. 85 86 87def assert_subprinter_registered(printer, subprinter): 88 # Match a line containing |printer| followed by a colon, and then a 89 # series of more-indented lines containing |subprinter|. 90 91 names = {"printer": re.escape(printer), "subprinter": re.escape(subprinter)} 92 pat = r"^( +)%(printer)s *\n(\1 +.*\n)*\1 +%(subprinter)s *\n" % names 93 output = gdb.execute("info pretty-printer", to_string=True) 94 if not re.search(pat, output, re.MULTILINE): 95 raise AssertionError( 96 "assert_subprinter_registered failed to find pretty-printer:\n" 97 " %s:%s\n" 98 "'info pretty-printer' says:\n" 99 "%s" % (printer, subprinter, output) 100 ) 101 102 103# Request full stack traces for Python errors. 104gdb.execute("set python print-stack full") 105 106# Tell GDB not to ask the user about the things we tell it to do. 107gdb.execute("set confirm off", False) 108 109# Some print settings that make testing easier. 110gdb.execute("set print static-members off") 111gdb.execute("set print address off") 112gdb.execute("set print pretty off") 113gdb.execute("set width 0") 114 115try: 116 # testscript is set on the GDB command line, via: 117 # --eval-command python testscript=... 118 execfile(testscript, globals(), locals()) 119except AssertionError as err: 120 header = "\nAssertion traceback" 121 if active_fragment: 122 header += " for " + active_fragment 123 sys.stderr.write(header + ":\n") 124 (t, v, tb) = sys.exc_info() 125 traceback.print_tb(tb) 126 sys.stderr.write("\nTest assertion failed:\n") 127 sys.stderr.write(str(err)) 128 sys.exit(1) 129