michael@0: import gdb michael@0: import os michael@0: import re michael@0: import sys michael@0: import traceback michael@0: michael@0: # testlibdir is set on the GDB command line, via --eval-command python testlibdir=... michael@0: sys.path[0:0] = [testlibdir] michael@0: michael@0: # Run the C++ fragment named |fragment|, stopping on entry to |function| michael@0: # ('breakpoint', by default) and then select the calling frame. michael@0: def run_fragment(fragment, function='breakpoint'): michael@0: # Arrange to stop at a reasonable place in the test program. michael@0: bp = gdb.Breakpoint(function); michael@0: try: michael@0: gdb.execute("run %s" % (fragment,)) michael@0: # Check that we did indeed stop by hitting the breakpoint we set. michael@0: assert bp.hit_count == 1 michael@0: finally: michael@0: bp.delete() michael@0: gdb.execute('frame 1') michael@0: michael@0: # Assert that |actual| is equal to |expected|; if not, complain in a helpful way. michael@0: def assert_eq(actual, expected): michael@0: if actual != expected: michael@0: raise AssertionError, """Unexpected result: michael@0: expected: %r michael@0: actual: %r""" % (expected, actual) michael@0: michael@0: # Assert that |value|'s pretty-printed form is |form|. If |value| is a michael@0: # string, then evaluate it with gdb.parse_and_eval to produce a value. michael@0: def assert_pretty(value, form): michael@0: if isinstance(value, str): michael@0: value = gdb.parse_and_eval(value) michael@0: assert_eq(str(value), form) michael@0: michael@0: # Check that the list of registered pretty-printers includes one named michael@0: # |printer|, with a subprinter named |subprinter|. michael@0: def assert_subprinter_registered(printer, subprinter): michael@0: # Match a line containing |printer| followed by a colon, and then a michael@0: # series of more-indented lines containing |subprinter|. michael@0: michael@0: names = { 'printer': re.escape(printer), 'subprinter': re.escape(subprinter) } michael@0: pat = r'^( +)%(printer)s *\n(\1 +.*\n)*\1 +%(subprinter)s *\n' % names michael@0: output = gdb.execute('info pretty-printer', to_string=True) michael@0: if not re.search(pat, output, re.MULTILINE): michael@0: raise AssertionError, ("assert_subprinter_registered failed to find pretty-printer:\n" michael@0: " %s:%s\n" michael@0: "'info pretty-printer' says:\n" michael@0: "%s" % (printer, subprinter, output)) michael@0: michael@0: # Request full stack traces for Python errors. michael@0: gdb.execute('set python print-stack full') michael@0: michael@0: # Tell GDB not to ask the user about the things we tell it to do. michael@0: gdb.execute('set confirm off', False) michael@0: michael@0: # Some print settings that make testing easier. michael@0: gdb.execute('set print static-members off') michael@0: gdb.execute('set print address off') michael@0: gdb.execute('set print pretty off') michael@0: gdb.execute('set width 0') michael@0: michael@0: try: michael@0: # testscript is set on the GDB command line, via: michael@0: # --eval-command python testscript=... michael@0: execfile(testscript) michael@0: except AssertionError as err: michael@0: sys.stderr.write('\nAssertion traceback:\n') michael@0: (t, v, tb) = sys.exc_info() michael@0: traceback.print_tb(tb) michael@0: sys.stderr.write('\nTest assertion failed:\n') michael@0: sys.stderr.write(str(err)) michael@0: sys.exit(1) michael@0: