Skip to content

Commit 1079b3e

Browse files
bpo-42540: reallocation of id_mutex should not force default allocator (GH-29564)
Unlike the other locks reinitialized by _PyRuntimeState_ReInitThreads, the "interpreters.main->id_mutex" is not freed by _PyRuntimeState_Fini and should not force the default raw allocator. (cherry picked from commit 736684b) Co-authored-by: Sam Gross <[email protected]>
1 parent 5618c81 commit 1079b3e

File tree

3 files changed

+22
-1
lines changed

3 files changed

+22
-1
lines changed

Lib/test/test_os.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4501,6 +4501,22 @@ def test_times(self):
45014501
self.assertEqual(times.elapsed, 0)
45024502

45034503

4504+
@requires_os_func('fork')
4505+
class ForkTests(unittest.TestCase):
4506+
def test_fork(self):
4507+
# bpo-42540: ensure os.fork() with non-default memory allocator does
4508+
# not crash on exit.
4509+
code = """if 1:
4510+
import os
4511+
from test import support
4512+
pid = os.fork()
4513+
if pid != 0:
4514+
support.wait_process(pid, exitcode=0)
4515+
"""
4516+
assert_python_ok("-c", code)
4517+
assert_python_ok("-c", code, PYTHONMALLOC="malloc_debug")
4518+
4519+
45044520
# Only test if the C version is provided, otherwise TestPEP519 already tested
45054521
# the pure Python implementation.
45064522
if hasattr(os, "_fspath"):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix crash when :func:`os.fork` is called with an active non-default
2+
memory allocator.

Python/pystate.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,12 +147,15 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime)
147147
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
148148

149149
int reinit_interp = _PyThread_at_fork_reinit(&runtime->interpreters.mutex);
150-
int reinit_main_id = _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex);
151150
int reinit_xidregistry = _PyThread_at_fork_reinit(&runtime->xidregistry.mutex);
152151
int reinit_unicode_ids = _PyThread_at_fork_reinit(&runtime->unicode_ids.lock);
153152

154153
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
155154

155+
/* bpo-42540: id_mutex is freed by _PyInterpreterState_Delete, which does
156+
* not force the default allocator. */
157+
int reinit_main_id = _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex);
158+
156159
if (reinit_interp < 0
157160
|| reinit_main_id < 0
158161
|| reinit_xidregistry < 0

0 commit comments

Comments
 (0)