Skip to content

Commit 308ffaf

Browse files
sobolevnebonnal
authored andcommitted
pythongh-126425: Refactor _lsprof_Profiler_enable (python#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
1 parent ae487ce commit 308ffaf

File tree

1 file changed

+25
-12
lines changed

1 file changed

+25
-12
lines changed

Modules/_lsprof.c

+25-12
Original file line numberDiff line numberDiff line change
@@ -780,34 +780,47 @@ _lsprof_Profiler_enable_impl(ProfilerObject *self, int subcalls,
780780
return NULL;
781781
}
782782

783-
if (PyObject_CallMethod(monitoring, "use_tool_id", "is", self->tool_id, "cProfile") == NULL) {
783+
PyObject *check = PyObject_CallMethod(monitoring,
784+
"use_tool_id", "is",
785+
self->tool_id, "cProfile");
786+
if (check == NULL) {
784787
PyErr_Format(PyExc_ValueError, "Another profiling tool is already active");
785-
Py_DECREF(monitoring);
786-
return NULL;
788+
goto error;
787789
}
790+
Py_DECREF(check);
788791

789792
for (int i = 0; callback_table[i].callback_method; i++) {
793+
int event = (1 << callback_table[i].event);
790794
PyObject* callback = PyObject_GetAttrString((PyObject*)self, callback_table[i].callback_method);
791795
if (!callback) {
792-
Py_DECREF(monitoring);
793-
return NULL;
796+
goto error;
794797
}
795-
Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id,
796-
(1 << callback_table[i].event),
797-
callback));
798+
PyObject *register_result = PyObject_CallMethod(monitoring, "register_callback",
799+
"iiO", self->tool_id,
800+
event, callback);
798801
Py_DECREF(callback);
799-
all_events |= (1 << callback_table[i].event);
802+
if (register_result == NULL) {
803+
goto error;
804+
}
805+
Py_DECREF(register_result);
806+
all_events |= event;
800807
}
801808

802-
if (!PyObject_CallMethod(monitoring, "set_events", "ii", self->tool_id, all_events)) {
803-
Py_DECREF(monitoring);
804-
return NULL;
809+
PyObject *event_result = PyObject_CallMethod(monitoring, "set_events", "ii",
810+
self->tool_id, all_events);
811+
if (event_result == NULL) {
812+
goto error;
805813
}
806814

815+
Py_DECREF(event_result);
807816
Py_DECREF(monitoring);
808817

809818
self->flags |= POF_ENABLED;
810819
Py_RETURN_NONE;
820+
821+
error:
822+
Py_DECREF(monitoring);
823+
return NULL;
811824
}
812825

813826
static void

0 commit comments

Comments
 (0)