From 33ecf3cc503d8c7e810a5f1741329e91a28ddee7 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Wed, 5 Mar 2025 16:41:03 -0500 Subject: [PATCH 1/3] Do not unpack method for legacy tracing anymore --- Lib/test/test_sys_setprofile.py | 20 ++++++++++++++++++++ Python/legacy_tracing.c | 13 ------------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/Lib/test/test_sys_setprofile.py b/Lib/test/test_sys_setprofile.py index 0753a9d8b8e0ee..44e21a646c6975 100644 --- a/Lib/test/test_sys_setprofile.py +++ b/Lib/test/test_sys_setprofile.py @@ -511,6 +511,26 @@ class B: ] ) + # Test CALL_FUNCTION_EX + events = [] + sys.setprofile(lambda frame, event, args: events.append(event)) + # Not important, we only want to trigger INSTRUMENTED_CALL_KW + args = (1,) + B().f(*args, key=lambda x: 0) + sys.setprofile(None) + # The last c_call is the call to sys.setprofile + # INSTRUMENTED_CALL_FUNCTION_EX has different behavior than the other + # instrumented call bytecodes, it does not unpack the callable before + # calling it. This is probably not ideal because it's not consistent, + # but at least we get a consistent call stack (no unmatched c_call). + self.assertEqual( + events, + ['call', 'return', + 'call', 'return', + 'c_call' + ] + ) + if __name__ == "__main__": unittest.main() diff --git a/Python/legacy_tracing.c b/Python/legacy_tracing.c index 97634f9183c7d5..82465c66ab5231 100644 --- a/Python/legacy_tracing.c +++ b/Python/legacy_tracing.c @@ -121,19 +121,6 @@ sys_profile_call_or_return( Py_DECREF(meth); return res; } - else if (Py_TYPE(callable) == &PyMethod_Type) { - // CALL instruction will grab the function from the method, - // so if the function is a C function, the return event will - // be emitted. However, CALL event happens before CALL - // instruction, so we need to handle this case here. - PyObject* func = PyMethod_GET_FUNCTION(callable); - if (func == NULL) { - return NULL; - } - if (PyCFunction_Check(func)) { - return call_profile_func(self, func); - } - } Py_RETURN_NONE; } From eb7fc824ca42be3802c3a94849348753c104fe0e Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Wed, 5 Mar 2025 21:52:23 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2025-03-05-21-52-20.gh-issue-122029.d_z93q.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-03-05-21-52-20.gh-issue-122029.d_z93q.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-03-05-21-52-20.gh-issue-122029.d_z93q.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-03-05-21-52-20.gh-issue-122029.d_z93q.rst new file mode 100644 index 00000000000000..6324f24d155389 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-03-05-21-52-20.gh-issue-122029.d_z93q.rst @@ -0,0 +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. From 66c8d8a7b2f2fe78496ea55ebe169cf6e8a9c1c5 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Tue, 11 Mar 2025 13:26:49 -0400 Subject: [PATCH 3/3] Update Lib/test/test_sys_setprofile.py Co-authored-by: Mark Shannon --- Lib/test/test_sys_setprofile.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_sys_setprofile.py b/Lib/test/test_sys_setprofile.py index 44e21a646c6975..345c022bd2374c 100644 --- a/Lib/test/test_sys_setprofile.py +++ b/Lib/test/test_sys_setprofile.py @@ -516,7 +516,8 @@ class B: sys.setprofile(lambda frame, event, args: events.append(event)) # Not important, we only want to trigger INSTRUMENTED_CALL_KW args = (1,) - B().f(*args, key=lambda x: 0) + m = B().f + m(*args, key=lambda x: 0) sys.setprofile(None) # The last c_call is the call to sys.setprofile # INSTRUMENTED_CALL_FUNCTION_EX has different behavior than the other