Skip to content

Py_Initialize() in a background thread crashes on free-threaded release builds of 3.14 after the mimalloc 2.5.2 update #160588

Closed

Description

@devdavidejesus

Crash report

On the 3.14 branch, a free-threaded release build (./configure --disable-gil) crashes when Py_Initialize() is called in a thread other than the main thread. test_embed's test_init_in_background_thread, added for gh-123022, fails on every run: ./Programs/_testembed test_init_in_background_thread crashed 20 times out of 20. Under lldb (trimmed):

$ lldb -- ./Programs/_testembed test_init_in_background_thread
* thread #2, stop reason = EXC_BAD_ACCESS (code=2, address=0x100411738)
  frame #0: chacha_block(ctx=0x00000001004116f8) at random.c:67:20
  frame #1: chacha_next32 at random.c:83:5 [inlined]
  frame #2: _mi_random_next at random.c:154:22 [inlined]
  frame #3: _mi_heap_random_next(heap=0x00000001004116c0) at heap.c:281:10 [inlined]
  frame #4: _mi_os_get_aligned_hint(try_alignment=33554432, size=1107296256) at os.c:129:19
  frame #5: unix_mmap_prim_aligned at prim.c:281:18
  ...
  frame #11: mi_reserve_os_memory_ex(size=1073741824, ...) at arena.c:917:17

It also fails in the tail-call workflow on my fork (x86_64-unknown-linux-gnu/gcc-free-threading, bad returncode -11): https://github.com/devdavidejesus/cpython/actions/runs/40045549694

In 3.14.9, _mi_os_get_aligned_hint() and mi_os_claim_huge_pages() in Objects/mimalloc/os.c only call _mi_heap_random_next() if mi_heap_is_initialized(heap); that check is the gh-123022 fix. The mimalloc 2.5.2 update (gh-159111, 1bcc0d1 on 3.14) dropped it. In a new thread the default heap is still _mi_heap_empty, which is const, so the write in chacha_block() faults (heap in frame #3 is _mi_heap_empty).

Debug builds are not affected, because this code is under #if (MI_SECURE>0 || MI_DEBUG==0) and MI_DEBUG is 2 with Py_DEBUG. The free-threaded jobs in the main CI workflow are debug builds, which is probably why this was not caught there.

The check is also missing on main and 3.15, but this test does not crash on main: there, as on 3.15, free-threaded builds use mimalloc for the raw domain (MIMALLOC_RAWALLOC), so the first PyMem_RawMalloc() call in the thread initializes its default heap. On 3.14 the raw domain uses malloc().

Restoring the check fixes the crash: the test then passes 20 of 20 times, and test_embed passes. (For main, gh-113141 notes that with mimalloc v3, proposed in gh-159718, "The gh-123022 patch no longer applies".)

CPython versions tested on:

3.14, CPython main branch

Operating systems tested on:

macOS, Linux

Output from running 'python -VV' on the command line:

Python 3.14.9+ free-threading build (remotes/upstream/3.14:aa3903e80a4, Oct 24 2026, 08:12:26) [Clang 21.0.0 (clang-2100.3.34.2)]

Linked PRs

Activity

  1. added a commit that references this issue on Oct 24, 2026
  2. added 2 commits that reference this issue on Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)topic-free-threadingtype-crashA hard crash of the interpreter, possibly with a core dump

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions