@@ -867,27 +867,40 @@ def test_gc(self):
867
867
# unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround
868
868
def test_pycfunction (self ):
869
869
'Verify that "py-bt" displays invocations of PyCFunction instances'
870
- # Tested function must not be defined with METH_NOARGS or METH_O,
871
- # otherwise call_function() doesn't call PyCFunction_Call()
872
- cmd = ('from time import gmtime\n '
873
- 'def foo():\n '
874
- ' gmtime(1)\n '
875
- 'def bar():\n '
876
- ' foo()\n '
877
- 'bar()\n ' )
878
- # Verify with "py-bt":
879
- gdb_output = self .get_stack_trace (cmd ,
880
- breakpoint = 'time_gmtime' ,
881
- cmds_after_breakpoint = ['bt' , 'py-bt' ],
882
- )
883
- self .assertIn ('<built-in method gmtime' , gdb_output )
884
-
885
- # Verify with "py-bt-full":
886
- gdb_output = self .get_stack_trace (cmd ,
887
- breakpoint = 'time_gmtime' ,
888
- cmds_after_breakpoint = ['py-bt-full' ],
889
- )
890
- self .assertIn ('#1 <built-in method gmtime' , gdb_output )
870
+ # Various optimizations multiply the code paths by which these are
871
+ # called, so test a variety of calling conventions.
872
+ for py_name , py_args , c_name , expected_frame_number in (
873
+ ('gmtime' , '' , 'time_gmtime' , 1 ), # METH_VARARGS
874
+ ('len' , '[]' , 'builtin_len' , 2 ), # METH_O
875
+ ('locals' , '' , 'builtin_locals' , 2 ), # METH_NOARGS
876
+ ('iter' , '[]' , 'builtin_iter' , 2 ), # METH_FASTCALL
877
+ ('sorted' , '[]' , 'builtin_sorted' , 2 ), # METH_FASTCALL|METH_KEYWORDS
878
+ ):
879
+ with self .subTest (c_name ):
880
+ cmd = ('from time import gmtime\n ' # (not always needed)
881
+ 'def foo():\n '
882
+ f' { py_name } ({ py_args } )\n '
883
+ 'def bar():\n '
884
+ ' foo()\n '
885
+ 'bar()\n ' )
886
+ # Verify with "py-bt":
887
+ gdb_output = self .get_stack_trace (
888
+ cmd ,
889
+ breakpoint = c_name ,
890
+ cmds_after_breakpoint = ['bt' , 'py-bt' ],
891
+ )
892
+ self .assertIn (f'<built-in method { py_name } ' , gdb_output )
893
+
894
+ # Verify with "py-bt-full":
895
+ gdb_output = self .get_stack_trace (
896
+ cmd ,
897
+ breakpoint = c_name ,
898
+ cmds_after_breakpoint = ['py-bt-full' ],
899
+ )
900
+ self .assertIn (
901
+ f'#{ expected_frame_number } <built-in method { py_name } ' ,
902
+ gdb_output ,
903
+ )
891
904
892
905
@unittest .skipIf (python_is_optimized (),
893
906
"Python was compiled with optimizations" )
0 commit comments