]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-131141: fix data race in instrumentation while registering callback (#131142)
authorKumar Aditya <kumaraditya@python.org>
Wed, 12 Mar 2025 18:41:52 +0000 (00:11 +0530)
committerGitHub <noreply@github.com>
Wed, 12 Mar 2025 18:41:52 +0000 (00:11 +0530)
Misc/NEWS.d/next/Core_and_Builtins/2025-03-12-11-19-46.gh-issue-131141.tQz594.rst [new file with mode: 0644]
Python/instrumentation.c

diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-03-12-11-19-46.gh-issue-131141.tQz594.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-03-12-11-19-46.gh-issue-131141.tQz594.rst
new file mode 100644 (file)
index 0000000..c1ea679
--- /dev/null
@@ -0,0 +1 @@
+Fix data race in :data:`sys.monitoring` instrumentation while registering callback.
index f871d1949db322276a15a5f268bbef16db20cdb8..c180f4c55c9e1a1b989244e0930b7d3a402903de 100644 (file)
@@ -3006,13 +3006,6 @@ static PyObject *make_branch_handler(int tool_id, PyObject *handler, bool right)
     return (PyObject *)callback;
 }
 
-/* Consumes a reference to obj */
-static PyObject *exchange_callables(int tool_id, int event_id, PyObject *obj)
-{
-    PyInterpreterState *is = _PyInterpreterState_GET();
-    return _Py_atomic_exchange_ptr(&is->monitoring_callables[tool_id][event_id], obj);
-}
-
 PyObject *
 _PyMonitoring_RegisterCallback(int tool_id, int event_id, PyObject *obj)
 {
@@ -3036,11 +3029,21 @@ _PyMonitoring_RegisterCallback(int tool_id, int event_id, PyObject *obj)
                 return NULL;
             }
         }
-        Py_XDECREF(exchange_callables(tool_id, PY_MONITORING_EVENT_BRANCH_RIGHT, right));
-        res = exchange_callables(tool_id, PY_MONITORING_EVENT_BRANCH_LEFT, left);
+        PyInterpreterState *interp = _PyInterpreterState_GET();
+        _PyEval_StopTheWorld(interp);
+        PyObject *old_right = interp->monitoring_callables[tool_id][PY_MONITORING_EVENT_BRANCH_RIGHT];
+        interp->monitoring_callables[tool_id][PY_MONITORING_EVENT_BRANCH_RIGHT] = right;
+        res = interp->monitoring_callables[tool_id][PY_MONITORING_EVENT_BRANCH_LEFT];
+        interp->monitoring_callables[tool_id][PY_MONITORING_EVENT_BRANCH_LEFT] = left;
+        _PyEval_StartTheWorld(interp);
+        Py_XDECREF(old_right);
     }
     else {
-        res = exchange_callables(tool_id, event_id, Py_XNewRef(obj));
+        PyInterpreterState *interp = _PyInterpreterState_GET();
+        _PyEval_StopTheWorld(interp);
+        res = interp->monitoring_callables[tool_id][event_id];
+        interp->monitoring_callables[tool_id][event_id] = Py_XNewRef(obj);
+        _PyEval_StartTheWorld(interp);
     }
     if (res != NULL && Py_TYPE(res) == &_PyLegacyBranchEventHandler_Type) {
         _PyLegacyBranchEventHandler *wrapper = (_PyLegacyBranchEventHandler *)res;