gh-135429: Fix the argument mismatch in lsprof throw event (#135442)

This commit is contained in:
Tian Gao 2025-06-12 14:46:47 -07:00 committed by GitHub
parent f273fd77d7
commit b03309fe5f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 68 additions and 11 deletions

View 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

View file

@ -0,0 +1 @@
Fix the argument mismatch in ``_lsprof`` for ``PY_THROW`` event.

View 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

View 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]*/