1 import textwrap
2 import unittest
3 from test import support
4
5 from .util import setup_module, DebuggerTests
6
7
8 def setUpModule():
9 setup_module()
10
11
12 @unittest.skipIf(support.python_is_optimized(),
13 "Python was compiled with optimizations")
14 @support.requires_resource('cpu')
15 class ESC[4;38;5;81mCFunctionTests(ESC[4;38;5;149mDebuggerTests):
16 def check(self, func_name, cmd):
17 # Verify with "py-bt":
18 gdb_output = self.get_stack_trace(
19 cmd,
20 breakpoint=func_name,
21 cmds_after_breakpoint=['bt', 'py-bt'],
22 # bpo-45207: Ignore 'Function "meth_varargs" not
23 # defined.' message in stderr.
24 ignore_stderr=True,
25 )
26 self.assertIn(f'<built-in method {func_name}', gdb_output)
27
28 # Some older versions of gdb will fail with
29 # "Cannot find new threads: generic error"
30 # unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround
31 #
32 # gdb will also generate many erroneous errors such as:
33 # Function "meth_varargs" not defined.
34 # This is because we are calling functions from an "external" module
35 # (_testcapimodule) rather than compiled-in functions. It seems difficult
36 # to suppress these. See also the comment in DebuggerTests.get_stack_trace
37 def check_pycfunction(self, func_name, args):
38 'Verify that "py-bt" displays invocations of PyCFunction instances'
39
40 if support.verbose:
41 print()
42
43 # Various optimizations multiply the code paths by which these are
44 # called, so test a variety of calling conventions.
45 for obj in (
46 '_testcapi',
47 '_testcapi.MethClass',
48 '_testcapi.MethClass()',
49 '_testcapi.MethStatic()',
50
51 # XXX: bound methods don't yet give nice tracebacks
52 # '_testcapi.MethInstance()',
53 ):
54 with self.subTest(f'{obj}.{func_name}'):
55 call = f'{obj}.{func_name}({args})'
56 cmd = textwrap.dedent(f'''
57 import _testcapi
58 def foo():
59 {call}
60 def bar():
61 foo()
62 bar()
63 ''')
64 if support.verbose:
65 print(f' test call: {call}', flush=True)
66
67 self.check(func_name, cmd)
68
69 def test_pycfunction_noargs(self):
70 self.check_pycfunction('meth_noargs', '')
71
72 def test_pycfunction_o(self):
73 self.check_pycfunction('meth_o', '[]')
74
75 def test_pycfunction_varargs(self):
76 self.check_pycfunction('meth_varargs', '')
77
78 def test_pycfunction_varargs_keywords(self):
79 self.check_pycfunction('meth_varargs_keywords', '')
80
81 def test_pycfunction_fastcall(self):
82 self.check_pycfunction('meth_fastcall', '')
83
84 def test_pycfunction_fastcall_keywords(self):
85 self.check_pycfunction('meth_fastcall_keywords', '')