cpython/Lib/test/test_gdb/test_cfunction.py
Victor Stinner 757cbd4f29
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.
2023-09-28 17:04:01 +00:00

86 lines
2.9 KiB
Python

import textwrap
import unittest
from test import support
from .util import setup_module, DebuggerTests
def setUpModule():
setup_module()
@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
#
# gdb will also generate many erroneous errors such as:
# Function "meth_varargs" not defined.
# 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 check_pycfunction(self, func_name, args):
'Verify that "py-bt" displays invocations of PyCFunction instances'
if support.verbose:
print()
# Various optimizations multiply the code paths by which these are
# called, so test a variety of calling conventions.
for obj in (
'_testcapi',
'_testcapi.MethClass',
'_testcapi.MethClass()',
'_testcapi.MethStatic()',
# XXX: bound methods don't yet give nice tracebacks
# '_testcapi.MethInstance()',
):
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)
self.check(func_name, cmd)
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', '')