]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-126425: Refactor `_lsprof_Profiler_enable` (#126426)
authorsobolevn <mail@sobolevn.me>
Tue, 5 Nov 2024 12:23:24 +0000 (15:23 +0300)
committerGitHub <noreply@github.com>
Tue, 5 Nov 2024 12:23:24 +0000 (15:23 +0300)
- 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

Modules/_lsprof.c

index 4f996c7230e16d52739c5786a78882349b4f0cb9..51ad9fc7da84924982c7738040538113114231be 100644 (file)
@@ -780,34 +780,47 @@ _lsprof_Profiler_enable_impl(ProfilerObject *self, int subcalls,
         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