gh-131141: fix data race in instrumentation while registering callback (#131142)

This commit is contained in:
Kumar Aditya 2025-03-13 00:11:52 +05:30 committed by GitHub
parent 25f24b01e3
commit ea57ffa02e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 14 additions and 10 deletions

View file

@ -0,0 +1 @@
Fix data race in :data:`sys.monitoring` instrumentation while registering callback.

View 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;