From 763abbc24b7cf0ee2999912ae465d01e16e17b66 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Tue, 5 Nov 2024 15:23:24 +0300 Subject: [PATCH] gh-126425: Refactor `_lsprof_Profiler_enable` (GH-126426) - Explicit memory management for `None` objects (since we still try to treat immortal objects as regular objects) - Respect possible errors of `sys.monitoring.register_callback` call (cherry picked from commit 75872605aa78dbdfc5c4f025b0f90a7f37ba10c3) Co-authored-by: sobolevn --- Modules/_lsprof.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index d11689906e574d..0464e7e8a44c0e 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -750,34 +750,47 @@ profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds) return NULL; } - if (PyObject_CallMethod(monitoring, "use_tool_id", "is", self->tool_id, "cProfile") == NULL) { + PyObject *check = PyObject_CallMethod(monitoring, + "use_tool_id", "is", + self->tool_id, "cProfile"); + if (check == NULL) { PyErr_Format(PyExc_ValueError, "Another profiling tool is already active"); - Py_DECREF(monitoring); - return NULL; + goto error; } + Py_DECREF(check); for (int i = 0; callback_table[i].callback_method; i++) { + int event = (1 << callback_table[i].event); PyObject* callback = PyObject_GetAttrString((PyObject*)self, callback_table[i].callback_method); if (!callback) { - Py_DECREF(monitoring); - return NULL; + goto error; } - Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, - (1 << callback_table[i].event), - callback)); + PyObject *register_result = PyObject_CallMethod(monitoring, "register_callback", + "iiO", self->tool_id, + event, callback); Py_DECREF(callback); - all_events |= (1 << callback_table[i].event); + if (register_result == NULL) { + goto error; + } + Py_DECREF(register_result); + all_events |= event; } - if (!PyObject_CallMethod(monitoring, "set_events", "ii", self->tool_id, all_events)) { - Py_DECREF(monitoring); - return NULL; + PyObject *event_result = PyObject_CallMethod(monitoring, "set_events", "ii", + self->tool_id, all_events); + if (event_result == NULL) { + goto error; } + Py_DECREF(event_result); Py_DECREF(monitoring); self->flags |= POF_ENABLED; Py_RETURN_NONE; + +error: + Py_DECREF(monitoring); + return NULL; } static void