From 31e2b76f7bbcb8278748565252767a8b7790ff27 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 6 Mar 2018 05:52:27 -0800 Subject: [PATCH] bpo-33005: Fix _PyGILState_Reinit() (GH-6001) Fix a crash on fork when using a custom memory allocator (ex: using PYTHONMALLOC env var). _PyGILState_Reinit() and _PyInterpreterState_Enable() now use the default RAW memory allocator to allocate a new interpreters mutex on fork. (cherry picked from commit 5d92647102fac9e116b98ab8bbc632eeed501c34) Co-authored-by: Victor Stinner --- .../2018-03-06-12-19-19.bpo-33005.LP-V2U.rst | 4 +++ Python/pystate.c | 27 ++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2018-03-06-12-19-19.bpo-33005.LP-V2U.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-03-06-12-19-19.bpo-33005.LP-V2U.rst b/Misc/NEWS.d/next/Core and Builtins/2018-03-06-12-19-19.bpo-33005.LP-V2U.rst new file mode 100644 index 0000000000..6c8b99cbb8 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-03-06-12-19-19.bpo-33005.LP-V2U.rst @@ -0,0 +1,4 @@ +Fix a crash on fork when using a custom memory allocator (ex: using +PYTHONMALLOC env var). _PyGILState_Reinit() and _PyInterpreterState_Enable() +now use the default RAW memory allocator to allocate a new interpreters mutex +on fork. diff --git a/Python/pystate.c b/Python/pystate.c index a87801f569..140d2fba8e 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -103,15 +103,24 @@ _PyInitError _PyInterpreterState_Enable(_PyRuntimeState *runtime) { runtime->interpreters.next_id = 0; - /* Since we only call _PyRuntimeState_Init() once per process - (see _PyRuntime_Initialize()), we make sure the mutex is - initialized here. */ + + /* Py_Finalize() calls _PyRuntimeState_Fini() which clears the mutex. + Create a new mutex if needed. */ if (runtime->interpreters.mutex == NULL) { + /* Force default allocator, since _PyRuntimeState_Fini() must + use the same allocator than this function. */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + runtime->interpreters.mutex = PyThread_allocate_lock(); + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + if (runtime->interpreters.mutex == NULL) { return _Py_INIT_ERR("Can't initialize threads for interpreter"); } } + return _Py_INIT_OK(); } @@ -933,9 +942,19 @@ _PyGILState_Fini(void) void _PyGILState_Reinit(void) { + /* Force default allocator, since _PyRuntimeState_Fini() must + use the same allocator than this function. */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + _PyRuntime.interpreters.mutex = PyThread_allocate_lock(); - if (_PyRuntime.interpreters.mutex == NULL) + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + if (_PyRuntime.interpreters.mutex == NULL) { Py_FatalError("Can't initialize threads for interpreter"); + } + PyThreadState *tstate = PyGILState_GetThisThreadState(); PyThread_tss_delete(&_PyRuntime.gilstate.autoTSSkey); if (PyThread_tss_create(&_PyRuntime.gilstate.autoTSSkey) != 0) { -- 2.40.0