diff --git a/Python/pystate.c b/Python/pystate.c index d10b38def32911..358328fe18db58 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -857,8 +857,6 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) */ // XXX Make sure we properly deal with problematic finalizers. - Py_CLEAR(interp->audit_hooks); - // gh-140257: Threads have already been cleared, but daemon threads may // still access eval_breaker atomically via take_gil() right before they // hang. Use an atomic store to prevent data races during finalization. diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 9442472b53abbe..3ad587da0c4d9e 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -235,8 +235,12 @@ should_audit(PyInterpreterState *interp) if (!interp) { return 0; } + // interp->audit_hooks can only ever be NULL very early during initialization + // or very late during finalization. + int interp_has_audit_hooks = (interp->audit_hooks != NULL + && PyList_GET_SIZE(interp->audit_hooks) > 0); return (interp->runtime->audit_hooks.head - || interp->audit_hooks + || interp_has_audit_hooks || PyDTrace_AUDIT_ENABLED()); } @@ -306,7 +310,9 @@ sys_audit_tstate(PyThreadState *ts, const char *event, } /* Call interpreter hooks */ - if (is->audit_hooks) { + PyObject *audit_hooks = is->audit_hooks; + assert(audit_hooks != NULL); + if (PyList_GET_SIZE(audit_hooks) > 0) { eventName = PyUnicode_FromString(event); if (!eventName) { goto exit; @@ -447,6 +453,8 @@ _PySys_ClearAuditHooks(PyThreadState *ts) PyMem_RawFree(e); e = n; } + + Py_CLEAR(ts->interp->audit_hooks); } static void @@ -536,15 +544,7 @@ sys_addaudithook_impl(PyObject *module, PyObject *hook) } PyInterpreterState *interp = tstate->interp; - if (interp->audit_hooks == NULL) { - interp->audit_hooks = PyList_New(0); - if (interp->audit_hooks == NULL) { - return NULL; - } - /* Avoid having our list of hooks show up in the GC module */ - PyObject_GC_UnTrack(interp->audit_hooks); - } - + assert(interp->audit_hooks != NULL); if (PyList_Append(interp->audit_hooks, hook) < 0) { return NULL; } @@ -4313,6 +4313,13 @@ _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p) PyInterpreterState *interp = tstate->interp; + PyObject *audit_hooks = PyList_New(0); + if (audit_hooks == NULL) { + goto error; + } + _PyObject_GC_UNTRACK(audit_hooks); + interp->audit_hooks = audit_hooks; + PyObject *modules = _PyImport_InitModules(interp); if (modules == NULL) { goto error;