diff options
author | Petr Viktorin <encukou@gmail.com> | 2019-06-02 21:11:24 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-02 21:11:24 (GMT) |
commit | 64e2c64f7f0111c52834155becc0c6134f9d8750 (patch) | |
tree | 492201b477926f0b1a4eea7425c771518a63757a | |
parent | cdce0574d03005e27b843fc110c54c99c7a76412 (diff) | |
download | cpython-64e2c64f7f0111c52834155becc0c6134f9d8750.zip cpython-64e2c64f7f0111c52834155becc0c6134f9d8750.tar.gz cpython-64e2c64f7f0111c52834155becc0c6134f9d8750.tar.bz2 |
test_gdb.test_pycfunction: test more calling conventions (GH-13668)
As the code paths for various METH_* conventions are diverging due
to optimizations, we should check they continue to be covered by
GDB integration.
-rw-r--r-- | Lib/test/test_gdb.py | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py index 3127e69..f57e348 100644 --- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -867,27 +867,40 @@ id(42) # unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround def test_pycfunction(self): 'Verify that "py-bt" displays invocations of PyCFunction instances' - # Tested function must not be defined with METH_NOARGS or METH_O, - # otherwise call_function() doesn't call PyCFunction_Call() - cmd = ('from time import gmtime\n' - 'def foo():\n' - ' gmtime(1)\n' - 'def bar():\n' - ' foo()\n' - 'bar()\n') - # Verify with "py-bt": - gdb_output = self.get_stack_trace(cmd, - breakpoint='time_gmtime', - cmds_after_breakpoint=['bt', 'py-bt'], - ) - self.assertIn('<built-in method gmtime', gdb_output) - - # Verify with "py-bt-full": - gdb_output = self.get_stack_trace(cmd, - breakpoint='time_gmtime', - cmds_after_breakpoint=['py-bt-full'], - ) - self.assertIn('#1 <built-in method gmtime', gdb_output) + # 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', 2), # METH_O + ('locals', '', 'builtin_locals', 2), # METH_NOARGS + ('iter', '[]', 'builtin_iter', 2), # METH_FASTCALL + ('sorted', '[]', 'builtin_sorted', 2), # METH_FASTCALL|METH_KEYWORDS + ): + 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, + ) @unittest.skipIf(python_is_optimized(), "Python was compiled with optimizations") |