summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_gdb/test_pretty_print.py
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2023-09-28 17:04:01 (GMT)
committerGitHub <noreply@github.com>2023-09-28 17:04:01 (GMT)
commit757cbd4f29c9e89b38b975e0463dc8ed331b2515 (patch)
tree84a65966c3e16e6833881568ad209ec936fac3ff /Lib/test/test_gdb/test_pretty_print.py
parentc4eda57345f579947b128e6148ab7f77de44bb88 (diff)
downloadcpython-757cbd4f29c9e89b38b975e0463dc8ed331b2515.zip
cpython-757cbd4f29c9e89b38b975e0463dc8ed331b2515.tar.gz
cpython-757cbd4f29c9e89b38b975e0463dc8ed331b2515.tar.bz2
gh-109972: Enhance test_gdb (#110026)
* Split test_pycfunction.py: add test_cfunction_full.py. Split the function into the following 6 functions. In verbose mode, these "pycfunction" tests now log each tested call. * test_pycfunction_noargs() * test_pycfunction_o() * test_pycfunction_varargs() * test_pycfunction_varargs_keywords() * test_pycfunction_fastcall() * test_pycfunction_fastcall_keywords() * Move get_gdb_repr() to PrettyPrintTests. * Replace DebuggerTests.get_sample_script() with SAMPLE_SCRIPT. * Rename checkout_hook_path to CHECKOUT_HOOK_PATH. * Rename gdb_version to GDB_VERSION_TEXT. * Replace (gdb_major_version, gdb_minor_version) with GDB_VERSION. * run_gdb() uses "backslashreplace" error handler instead of "replace". * Add check_gdb() function to util.py. * Enhance support.check_cflags_pgo(): check also for sysconfig PGO_PROF_USE_FLAG (if available) in compiler flags. * Move some SkipTest checks to test_gdb/__init__.py. * Elaborate why gdb cannot be tested on Windows: gdb doesn't support PDB debug symbol files.
Diffstat (limited to 'Lib/test/test_gdb/test_pretty_print.py')
-rw-r--r--Lib/test/test_gdb/test_pretty_print.py54
1 files changed, 46 insertions, 8 deletions
diff --git a/Lib/test/test_gdb/test_pretty_print.py b/Lib/test/test_gdb/test_pretty_print.py
index e31dc66..dfc77d6 100644
--- a/Lib/test/test_gdb/test_pretty_print.py
+++ b/Lib/test/test_gdb/test_pretty_print.py
@@ -3,7 +3,7 @@ import sys
from test import support
from .util import (
- BREAKPOINT_FN, gdb_major_version, gdb_minor_version,
+ BREAKPOINT_FN, GDB_VERSION,
run_gdb, setup_module, DebuggerTests)
@@ -12,6 +12,42 @@ def setUpModule():
class PrettyPrintTests(DebuggerTests):
+ def get_gdb_repr(self, source,
+ cmds_after_breakpoint=None,
+ import_site=False):
+ # Given an input python source representation of data,
+ # run "python -c'id(DATA)'" under gdb with a breakpoint on
+ # builtin_id and scrape out gdb's representation of the "op"
+ # parameter, and verify that the gdb displays the same string
+ #
+ # Verify that the gdb displays the expected string
+ #
+ # For a nested structure, the first time we hit the breakpoint will
+ # give us the top-level structure
+
+ # NOTE: avoid decoding too much of the traceback as some
+ # undecodable characters may lurk there in optimized mode
+ # (issue #19743).
+ cmds_after_breakpoint = cmds_after_breakpoint or ["backtrace 1"]
+ gdb_output = self.get_stack_trace(source, breakpoint=BREAKPOINT_FN,
+ cmds_after_breakpoint=cmds_after_breakpoint,
+ import_site=import_site)
+ # gdb can insert additional '\n' and space characters in various places
+ # in its output, depending on the width of the terminal it's connected
+ # to (using its "wrap_here" function)
+ m = re.search(
+ # Match '#0 builtin_id(self=..., v=...)'
+ r'#0\s+builtin_id\s+\(self\=.*,\s+v=\s*(.*?)?\)'
+ # Match ' at Python/bltinmodule.c'.
+ # bpo-38239: builtin_id() is defined in Python/bltinmodule.c,
+ # but accept any "Directory\file.c" to support Link Time
+ # Optimization (LTO).
+ r'\s+at\s+\S*[A-Za-z]+/[A-Za-z0-9_-]+\.c',
+ gdb_output, re.DOTALL)
+ if not m:
+ self.fail('Unexpected gdb output: %r\n%s' % (gdb_output, gdb_output))
+ return m.group(1), gdb_output
+
def test_getting_backtrace(self):
gdb_output = self.get_stack_trace('id(42)')
self.assertTrue(BREAKPOINT_FN in gdb_output)
@@ -75,15 +111,17 @@ class PrettyPrintTests(DebuggerTests):
# as GDB might have been linked against a different version
# of Python with a different encoding and coercion policy
# with respect to PEP 538 and PEP 540.
- out, err = run_gdb(
+ stdout, stderr = run_gdb(
'--eval-command',
'python import locale; print(locale.getpreferredencoding())')
- encoding = out.rstrip()
- if err or not encoding:
+ encoding = stdout
+ if stderr or not encoding:
raise RuntimeError(
- f'unable to determine the preferred encoding '
- f'of embedded Python in GDB: {err}')
+ f'unable to determine the Python locale preferred encoding '
+ f'of embedded Python in GDB\n'
+ f'stdout={stdout!r}\n'
+ f'stderr={stderr!r}')
def check_repr(text):
try:
@@ -122,7 +160,7 @@ class PrettyPrintTests(DebuggerTests):
@support.requires_resource('cpu')
def test_sets(self):
'Verify the pretty-printing of sets'
- if (gdb_major_version, gdb_minor_version) < (7, 3):
+ if GDB_VERSION < (7, 3):
self.skipTest("pretty-printing of sets needs gdb 7.3 or later")
self.assertGdbRepr(set(), "set()")
self.assertGdbRepr(set(['a']), "{'a'}")
@@ -141,7 +179,7 @@ id(s)''')
@support.requires_resource('cpu')
def test_frozensets(self):
'Verify the pretty-printing of frozensets'
- if (gdb_major_version, gdb_minor_version) < (7, 3):
+ if GDB_VERSION < (7, 3):
self.skipTest("pretty-printing of frozensets needs gdb 7.3 or later")
self.assertGdbRepr(frozenset(), "frozenset()")
self.assertGdbRepr(frozenset(['a']), "frozenset({'a'})")