mirror of
https://github.com/python/cpython.git
synced 2025-10-07 15:42:02 +00:00
* 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. (cherry picked from commit757cbd4f29
) * gh-104736: Fix test_gdb tests on ppc64le with clang (#109360) Fix test_gdb on Python built with LLVM clang 16 on Linux ppc64le (ex: Fedora 38). Search patterns in gdb "bt" command output to detect when gdb fails to retrieve the traceback. For example, skip a test if "Backtrace stopped: frame did not save the PC" is found. (cherry picked from commit44d9a71ea2
) * gh-110166: Fix gdb CFunctionFullTests on ppc64le clang build (#110331) CFunctionFullTests now also runs "bt" command before "py-bt-full", similar to CFunctionTests which also runs "bt" command before "py-bt". So test_gdb can skip the test if patterns like "?? ()" are found in the gdb output. (cherry picked from commit1de9406f91
)
This commit is contained in:
parent
1d032ea3d6
commit
bbce8bd05d
9 changed files with 303 additions and 218 deletions
|
@ -1,8 +1,6 @@
|
|||
import re
|
||||
import textwrap
|
||||
import unittest
|
||||
from test import support
|
||||
from test.support import python_is_optimized
|
||||
|
||||
from .util import setup_module, DebuggerTests
|
||||
|
||||
|
@ -11,10 +9,22 @@ def setUpModule():
|
|||
setup_module()
|
||||
|
||||
|
||||
@unittest.skipIf(python_is_optimized(),
|
||||
@unittest.skipIf(support.python_is_optimized(),
|
||||
"Python was compiled with optimizations")
|
||||
@support.requires_resource('cpu')
|
||||
class CFunctionTests(DebuggerTests):
|
||||
def check(self, func_name, cmd):
|
||||
# Verify with "py-bt":
|
||||
gdb_output = self.get_stack_trace(
|
||||
cmd,
|
||||
breakpoint=func_name,
|
||||
cmds_after_breakpoint=['bt', 'py-bt'],
|
||||
# bpo-45207: Ignore 'Function "meth_varargs" not
|
||||
# defined.' message in stderr.
|
||||
ignore_stderr=True,
|
||||
)
|
||||
self.assertIn(f'<built-in method {func_name}', gdb_output)
|
||||
|
||||
# Some older versions of gdb will fail with
|
||||
# "Cannot find new threads: generic error"
|
||||
# unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround
|
||||
|
@ -24,60 +34,52 @@ class CFunctionTests(DebuggerTests):
|
|||
# This is because we are calling functions from an "external" module
|
||||
# (_testcapimodule) rather than compiled-in functions. It seems difficult
|
||||
# to suppress these. See also the comment in DebuggerTests.get_stack_trace
|
||||
def test_pycfunction(self):
|
||||
def check_pycfunction(self, func_name, args):
|
||||
'Verify that "py-bt" displays invocations of PyCFunction instances'
|
||||
# bpo-46600: If the compiler inlines _null_to_none() in meth_varargs()
|
||||
# (ex: clang -Og), _null_to_none() is the frame #1. Otherwise,
|
||||
# meth_varargs() is the frame #1.
|
||||
expected_frame = r'#(1|2)'
|
||||
|
||||
if support.verbose:
|
||||
print()
|
||||
|
||||
# Various optimizations multiply the code paths by which these are
|
||||
# called, so test a variety of calling conventions.
|
||||
for func_name, args in (
|
||||
('meth_varargs', ''),
|
||||
('meth_varargs_keywords', ''),
|
||||
('meth_o', '[]'),
|
||||
('meth_noargs', ''),
|
||||
('meth_fastcall', ''),
|
||||
('meth_fastcall_keywords', ''),
|
||||
for obj in (
|
||||
'_testcapi',
|
||||
'_testcapi.MethClass',
|
||||
'_testcapi.MethClass()',
|
||||
'_testcapi.MethStatic()',
|
||||
|
||||
# XXX: bound methods don't yet give nice tracebacks
|
||||
# '_testcapi.MethInstance()',
|
||||
):
|
||||
for obj in (
|
||||
'_testcapi',
|
||||
'_testcapi.MethClass',
|
||||
'_testcapi.MethClass()',
|
||||
'_testcapi.MethStatic()',
|
||||
with self.subTest(f'{obj}.{func_name}'):
|
||||
call = f'{obj}.{func_name}({args})'
|
||||
cmd = textwrap.dedent(f'''
|
||||
import _testcapi
|
||||
def foo():
|
||||
{call}
|
||||
def bar():
|
||||
foo()
|
||||
bar()
|
||||
''')
|
||||
if support.verbose:
|
||||
print(f' test call: {call}', flush=True)
|
||||
|
||||
# XXX: bound methods don't yet give nice tracebacks
|
||||
# '_testcapi.MethInstance()',
|
||||
):
|
||||
with self.subTest(f'{obj}.{func_name}'):
|
||||
cmd = textwrap.dedent(f'''
|
||||
import _testcapi
|
||||
def foo():
|
||||
{obj}.{func_name}({args})
|
||||
def bar():
|
||||
foo()
|
||||
bar()
|
||||
''')
|
||||
# Verify with "py-bt":
|
||||
gdb_output = self.get_stack_trace(
|
||||
cmd,
|
||||
breakpoint=func_name,
|
||||
cmds_after_breakpoint=['bt', 'py-bt'],
|
||||
# bpo-45207: Ignore 'Function "meth_varargs" not
|
||||
# defined.' message in stderr.
|
||||
ignore_stderr=True,
|
||||
)
|
||||
self.assertIn(f'<built-in method {func_name}', gdb_output)
|
||||
self.check(func_name, cmd)
|
||||
|
||||
# Verify with "py-bt-full":
|
||||
gdb_output = self.get_stack_trace(
|
||||
cmd,
|
||||
breakpoint=func_name,
|
||||
cmds_after_breakpoint=['py-bt-full'],
|
||||
# bpo-45207: Ignore 'Function "meth_varargs" not
|
||||
# defined.' message in stderr.
|
||||
ignore_stderr=True,
|
||||
)
|
||||
regex = expected_frame
|
||||
regex += re.escape(f' <built-in method {func_name}')
|
||||
self.assertRegex(gdb_output, regex)
|
||||
def test_pycfunction_noargs(self):
|
||||
self.check_pycfunction('meth_noargs', '')
|
||||
|
||||
def test_pycfunction_o(self):
|
||||
self.check_pycfunction('meth_o', '[]')
|
||||
|
||||
def test_pycfunction_varargs(self):
|
||||
self.check_pycfunction('meth_varargs', '')
|
||||
|
||||
def test_pycfunction_varargs_keywords(self):
|
||||
self.check_pycfunction('meth_varargs_keywords', '')
|
||||
|
||||
def test_pycfunction_fastcall(self):
|
||||
self.check_pycfunction('meth_fastcall', '')
|
||||
|
||||
def test_pycfunction_fastcall_keywords(self):
|
||||
self.check_pycfunction('meth_fastcall_keywords', '')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue