Skip to content

Commit 6af20ed

Browse files
gaogaotiantianseehwan80
authored andcommitted
pythongh-122029: Do not unpack method for legacy tracing anymore (python#130898)
1 parent 4bdc13c commit 6af20ed

File tree

3 files changed

+22
-13
lines changed

3 files changed

+22
-13
lines changed

Lib/test/test_sys_setprofile.py

+21
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,27 @@ class B:
511511
]
512512
)
513513

514+
# Test CALL_FUNCTION_EX
515+
events = []
516+
sys.setprofile(lambda frame, event, args: events.append(event))
517+
# Not important, we only want to trigger INSTRUMENTED_CALL_KW
518+
args = (1,)
519+
m = B().f
520+
m(*args, key=lambda x: 0)
521+
sys.setprofile(None)
522+
# The last c_call is the call to sys.setprofile
523+
# INSTRUMENTED_CALL_FUNCTION_EX has different behavior than the other
524+
# instrumented call bytecodes, it does not unpack the callable before
525+
# calling it. This is probably not ideal because it's not consistent,
526+
# but at least we get a consistent call stack (no unmatched c_call).
527+
self.assertEqual(
528+
events,
529+
['call', 'return',
530+
'call', 'return',
531+
'c_call'
532+
]
533+
)
534+
514535

515536
if __name__ == "__main__":
516537
unittest.main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:func:`sys.setprofile` and :func:`sys.settrace` will not generate a ``c_call`` event for ``INSTRUMENTED_CALL_FUNCTION_EX`` if the callable is a method with a C function wrapped, because we do not generate ``c_return`` event in such case.

Python/legacy_tracing.c

-13
Original file line numberDiff line numberDiff line change
@@ -121,19 +121,6 @@ sys_profile_call_or_return(
121121
Py_DECREF(meth);
122122
return res;
123123
}
124-
else if (Py_TYPE(callable) == &PyMethod_Type) {
125-
// CALL instruction will grab the function from the method,
126-
// so if the function is a C function, the return event will
127-
// be emitted. However, CALL event happens before CALL
128-
// instruction, so we need to handle this case here.
129-
PyObject* func = PyMethod_GET_FUNCTION(callable);
130-
if (func == NULL) {
131-
return NULL;
132-
}
133-
if (PyCFunction_Check(func)) {
134-
return call_profile_func(self, func);
135-
}
136-
}
137124
Py_RETURN_NONE;
138125
}
139126

0 commit comments

Comments
 (0)