]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
test_gdb.test_pycfunction: test more calling conventions (GH-13668)
authorPetr Viktorin <encukou@gmail.com>
Sun, 2 Jun 2019 21:11:24 +0000 (23:11 +0200)
committerGitHub <noreply@github.com>
Sun, 2 Jun 2019 21:11:24 +0000 (23:11 +0200)
As the code paths for various METH_* conventions are diverging due
to optimizations, we should check they continue to be covered by
GDB integration.

Lib/test/test_gdb.py

index 3127e69ca9ba1dc638bbc6898d811614ed6b83d7..f57e348b6c144c7b32167260f5961d24cfef9416 100644 (file)
@@ -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")