Skip to content

Commit 87787c8

Browse files
authored
[3.9] bpo-42540: reallocation of id_mutex should not force default allocator (GH-29564) (GH-29600)
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 ac89f8c commit 87787c8

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
@@ -4273,6 +4273,22 @@ def test_times(self):
42734273
self.assertEqual(times.elapsed, 0)
42744274

42754275

4276+
@requires_os_func('fork')
4277+
class ForkTests(unittest.TestCase):
4278+
def test_fork(self):
4279+
# bpo-42540: ensure os.fork() with non-default memory allocator does
4280+
# not crash on exit.
4281+
code = """if 1:
4282+
import os
4283+
from test import support
4284+
pid = os.fork()
4285+
if pid != 0:
4286+
support.wait_process(pid, exitcode=0)
4287+
"""
4288+
assert_python_ok("-c", code)
4289+
assert_python_ok("-c", code, PYTHONMALLOC="malloc_debug")
4290+
4291+
42764292
# Only test if the C version is provided, otherwise TestPEP519 already tested
42774293
# the pure Python implementation.
42784294
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
@@ -139,11 +139,14 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime)
139139
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
140140

141141
int interp_mutex = _PyThread_at_fork_reinit(&runtime->interpreters.mutex);
142-
int main_interp_id_mutex = _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex);
143142
int xidregistry_mutex = _PyThread_at_fork_reinit(&runtime->xidregistry.mutex);
144143

145144
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
146145

146+
/* bpo-42540: id_mutex is freed by _PyInterpreterState_Delete, which does
147+
* not force the default allocator. */
148+
int main_interp_id_mutex = _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex);
149+
147150
if (interp_mutex < 0) {
148151
Py_FatalError("Can't initialize lock for runtime interpreters");
149152
}

0 commit comments

Comments
 (0)