diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-11-05-10-51-17.gh-issue-161407.rVoqaQ.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-11-05-10-51-17.gh-issue-161407.rVoqaQ.rst new file mode 100644 index 000000000000000..421329930f961a7 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-11-05-10-51-17.gh-issue-161407.rVoqaQ.rst @@ -0,0 +1,3 @@ +Fix a crash at exit when an audit hook was added with :c:func:`PySys_AddAuditHook` +before :c:func:`Py_Initialize` and the raw memory allocator changed during startup, for +example with ``PYTHONMALLOC=mimalloc`` or in the :ref:`Python Development Mode `. diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 6f336dac058379e..e8dd956c3f48828 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -448,7 +448,7 @@ _PySys_ClearAuditHooks(PyThreadState *ts) runtime->audit_hooks.head = NULL; while (e) { n = e->next; - PyMem_RawFree(e); + free(e); e = n; } } @@ -496,7 +496,11 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) } } - _Py_AuditHookEntry *e = (_Py_AuditHookEntry*)PyMem_RawMalloc( + /* Use malloc(), not PyMem_RawMalloc(): a hook can be added before + Py_Initialize(), and the entry is freed during finalization, after + PYTHONMALLOC may have changed the raw allocator (and, in debug builds, + the allocator under the debug hooks). */ + _Py_AuditHookEntry *e = (_Py_AuditHookEntry*)malloc( sizeof(_Py_AuditHookEntry)); if (!e) { if (tstate != NULL) {