]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-135429: Fix the argument mismatch in lsprof throw event (#135442)
authorTian Gao <gaogaotiantian@hotmail.com>
Thu, 12 Jun 2025 21:46:47 +0000 (14:46 -0700)
committerGitHub <noreply@github.com>
Thu, 12 Jun 2025 21:46:47 +0000 (14:46 -0700)
Lib/test/test_cprofile.py
Misc/NEWS.d/next/Library/2025-06-12-18-15-31.gh-issue-135429.mch75_.rst [new file with mode: 0644]
Modules/_lsprof.c
Modules/clinic/_lsprof.c.h

index 192c8eab26ebff3a505b98e2c5ca7f1cc2926a79..57e818b1c68b3881a9535ca1a19effbd2a0d8d6b 100644 (file)
@@ -125,21 +125,22 @@ class CProfileTest(ProfileTest):
         """
         gh-106152
         generator.throw() should trigger a call in cProfile
-        In the any() call below, there should be two entries for the generator:
-            * one for the call to __next__ which gets a True and terminates any
-            * one when the generator is garbage collected which will effectively
-              do a throw.
         """
+
+        def gen():
+            yield
+
         pr = self.profilerclass()
         pr.enable()
-        any(a == 1 for a in (1, 2))
+        g = gen()
+        try:
+            g.throw(SyntaxError)
+        except SyntaxError:
+            pass
         pr.disable()
         pr.create_stats()
 
-        for func, (cc, nc, _, _, _) in pr.stats.items():
-            if func[2] == "<genexpr>":
-                self.assertEqual(cc, 1)
-                self.assertEqual(nc, 1)
+        self.assertTrue(any("throw" in func[2] for func in pr.stats.keys())),
 
     def test_bad_descriptor(self):
         # gh-132250
diff --git a/Misc/NEWS.d/next/Library/2025-06-12-18-15-31.gh-issue-135429.mch75_.rst b/Misc/NEWS.d/next/Library/2025-06-12-18-15-31.gh-issue-135429.mch75_.rst
new file mode 100644 (file)
index 0000000..b521352
--- /dev/null
@@ -0,0 +1 @@
+Fix the argument mismatch in ``_lsprof`` for ``PY_THROW`` event.
index bbad5eb69032da6946cbd43ff623a6dfca286a6e..d0074b2a0d1f4df355875b54297cda56ea4f8f82 100644 (file)
@@ -631,6 +631,27 @@ _lsprof_Profiler__pystart_callback_impl(ProfilerObject *self, PyObject *code,
     Py_RETURN_NONE;
 }
 
+/*[clinic input]
+_lsprof.Profiler._pythrow_callback
+
+    code: object
+    instruction_offset: object
+    exception: object
+    /
+
+[clinic start generated code]*/
+
+static PyObject *
+_lsprof_Profiler__pythrow_callback_impl(ProfilerObject *self, PyObject *code,
+                                        PyObject *instruction_offset,
+                                        PyObject *exception)
+/*[clinic end generated code: output=0a32988919dfb94c input=fd728fc2c074f5e6]*/
+{
+    ptrace_enter_call((PyObject*)self, (void *)code, code);
+
+    Py_RETURN_NONE;
+}
+
 /*[clinic input]
 _lsprof.Profiler._pyreturn_callback
 
@@ -747,7 +768,7 @@ static const struct {
 } callback_table[] = {
     {PY_MONITORING_EVENT_PY_START, "_pystart_callback"},
     {PY_MONITORING_EVENT_PY_RESUME, "_pystart_callback"},
-    {PY_MONITORING_EVENT_PY_THROW, "_pystart_callback"},
+    {PY_MONITORING_EVENT_PY_THROW, "_pythrow_callback"},
     {PY_MONITORING_EVENT_PY_RETURN, "_pyreturn_callback"},
     {PY_MONITORING_EVENT_PY_YIELD, "_pyreturn_callback"},
     {PY_MONITORING_EVENT_PY_UNWIND, "_pyreturn_callback"},
@@ -1002,6 +1023,7 @@ static PyMethodDef profiler_methods[] = {
     _LSPROF_PROFILER_DISABLE_METHODDEF
     _LSPROF_PROFILER_CLEAR_METHODDEF
     _LSPROF_PROFILER__PYSTART_CALLBACK_METHODDEF
+    _LSPROF_PROFILER__PYTHROW_CALLBACK_METHODDEF
     _LSPROF_PROFILER__PYRETURN_CALLBACK_METHODDEF
     _LSPROF_PROFILER__CCALL_CALLBACK_METHODDEF
     _LSPROF_PROFILER__CRETURN_CALLBACK_METHODDEF
index 2918a6bc7abe7482c0764112db6ba3cad817f64c..c426cd6fe02f398308456f02ba7d3261748d87f6 100644 (file)
@@ -82,6 +82,39 @@ exit:
     return return_value;
 }
 
+PyDoc_STRVAR(_lsprof_Profiler__pythrow_callback__doc__,
+"_pythrow_callback($self, code, instruction_offset, exception, /)\n"
+"--\n"
+"\n");
+
+#define _LSPROF_PROFILER__PYTHROW_CALLBACK_METHODDEF    \
+    {"_pythrow_callback", _PyCFunction_CAST(_lsprof_Profiler__pythrow_callback), METH_FASTCALL, _lsprof_Profiler__pythrow_callback__doc__},
+
+static PyObject *
+_lsprof_Profiler__pythrow_callback_impl(ProfilerObject *self, PyObject *code,
+                                        PyObject *instruction_offset,
+                                        PyObject *exception);
+
+static PyObject *
+_lsprof_Profiler__pythrow_callback(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *code;
+    PyObject *instruction_offset;
+    PyObject *exception;
+
+    if (!_PyArg_CheckPositional("_pythrow_callback", nargs, 3, 3)) {
+        goto exit;
+    }
+    code = args[0];
+    instruction_offset = args[1];
+    exception = args[2];
+    return_value = _lsprof_Profiler__pythrow_callback_impl((ProfilerObject *)self, code, instruction_offset, exception);
+
+exit:
+    return return_value;
+}
+
 PyDoc_STRVAR(_lsprof_Profiler__pyreturn_callback__doc__,
 "_pyreturn_callback($self, code, instruction_offset, retval, /)\n"
 "--\n"
@@ -411,4 +444,4 @@ skip_optional_pos:
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=fe231309776df7a7 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=9e46985561166c37 input=a9049054013a1b77]*/