| 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', '') |