diff options
author | Petr Viktorin <encukou@gmail.com> | 2019-09-10 11:21:09 (GMT) |
---|---|---|
committer | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2019-09-10 11:21:09 (GMT) |
commit | f958377b67c36a98d4df67b94c01eb29e3104f61 (patch) | |
tree | 9258fb47193c6d18c3a6a2c3fe4f64d7b1199ce8 /Lib/test/test_gdb.py | |
parent | f1a297acb60b88917712450ebd3cfa707e6efd6b (diff) | |
download | cpython-f958377b67c36a98d4df67b94c01eb29e3104f61.zip cpython-f958377b67c36a98d4df67b94c01eb29e3104f61.tar.gz cpython-f958377b67c36a98d4df67b94c01eb29e3104f61.tar.bz2 |
bpo-37499: Test various C calling conventions (GH-15776)
Add functions with various calling conventions to `_testcapi`, expose them as module-level functions, bound methods, class methods, and static methods, and test calling them and introspecting them through GDB.
https://bugs.python.org/issue37499
Co-authored-by: Jeroen Demeyer <J.Demeyer@UGent.be>
Automerge-Triggered-By: @pganssle
Diffstat (limited to 'Lib/test/test_gdb.py')
-rw-r--r-- | Lib/test/test_gdb.py | 81 |
1 files changed, 50 insertions, 31 deletions
diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py index a2aa16c..e515d0d 100644 --- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -838,47 +838,66 @@ id(42) ) self.assertIn('Garbage-collecting', gdb_output) + @unittest.skipIf(python_is_optimized(), "Python was compiled with optimizations") # 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 test_pycfunction(self): 'Verify that "py-bt" displays invocations of PyCFunction instances' # Various optimizations multiply the code paths by which these are # called, so test a variety of calling conventions. - for py_name, py_args, c_name, expected_frame_number in ( - ('gmtime', '', 'time_gmtime', 1), # METH_VARARGS - ('len', '[]', 'builtin_len', 1), # METH_O - ('locals', '', 'builtin_locals', 1), # METH_NOARGS - ('iter', '[]', 'builtin_iter', 1), # METH_FASTCALL - ('sorted', '[]', 'builtin_sorted', 1), # METH_FASTCALL|METH_KEYWORDS + for func_name, args, expected_frame in ( + ('meth_varargs', '', 1), + ('meth_varargs_keywords', '', 1), + ('meth_o', '[]', 1), + ('meth_noargs', '', 1), + ('meth_fastcall', '', 1), + ('meth_fastcall_keywords', '', 1), ): - with self.subTest(c_name): - cmd = ('from time import gmtime\n' # (not always needed) - 'def foo():\n' - f' {py_name}({py_args})\n' - 'def bar():\n' - ' foo()\n' - 'bar()\n') - # Verify with "py-bt": - gdb_output = self.get_stack_trace( - cmd, - breakpoint=c_name, - cmds_after_breakpoint=['bt', 'py-bt'], - ) - self.assertIn(f'<built-in method {py_name}', gdb_output) - - # Verify with "py-bt-full": - gdb_output = self.get_stack_trace( - cmd, - breakpoint=c_name, - cmds_after_breakpoint=['py-bt-full'], - ) - self.assertIn( - f'#{expected_frame_number} <built-in method {py_name}', - gdb_output, - ) + 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}'): + 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'], + ) + self.assertIn(f'<built-in method {func_name}', gdb_output) + + # Verify with "py-bt-full": + gdb_output = self.get_stack_trace( + cmd, + breakpoint=func_name, + cmds_after_breakpoint=['py-bt-full'], + ) + self.assertIn( + f'#{expected_frame} <built-in method {func_name}', + gdb_output, + ) @unittest.skipIf(python_is_optimized(), "Python was compiled with optimizations") |