Skip to content

fix: bootstrap the library in mi_heap_new and mi_subproc_new - #1351

Merged
Daan (daanx) merged 1 commit into
microsoft:dev3from
zackees:pr/bootstrap-dev3
Aug 2, 2026
Merged

fix: bootstrap the library in mi_heap_new and mi_subproc_new#1351
Daan (daanx) merged 1 commit into
microsoft:dev3from
zackees:pr/bootstrap-dev3

Conversation

@zackees

Copy link
Copy Markdown
Contributor

The defect

mi_heap_new and mi_subproc_new can each be the very first mimalloc call in a process. When they are, the main heap does not exist yet:

  • mi_heap_new_in_arena_mi_heap_new_for_subproc allocates from a NULL subproc->heap_main.
  • mi_subproc_new_mi_meta_zalloc(parent, ...) allocates out of the parent's main heap, which is likewise not there.

On platforms with a library constructor, something has always initialized the allocator earlier — which is why this only surfaces on Windows. Same class as #1341 (free(NULL) before init).

The fix

mi_thread_init() is the idempotent bootstrap the allocation path already performs, and it calls mi_process_init() in turn. Both call sites just need to do what a first malloc would have done.

Measurement

On this commit (1f06f694), MinGW-w64 GCC 12.2 x86_64, configured exactly as .github/workflows/test.yaml does for its basic matrix entry (-DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON):

Before

67% tests passed, 2 tests failed out of 6

The following tests FAILED:
   3 - test-stress-heaps     (Exit code 0xc0000409)
   4 - test-stress-subprocs  (Exit code 0xc0000409)

After

100% tests passed, 0 tests failed out of 6

0xc0000409 is Windows fail-fast, so these are hard aborts rather than assertion failures. Configure and build are clean in both cases — the difference is entirely at runtime.

Why this has gone unnoticed

Both failing tests are already in the repository and pass under MSVC. There is no MinGW job in CI, so nothing exercises the configuration in which the missing bootstrap is reachable.

That is worth mentioning because it is the root cause of a small cluster: the MinGW TLS-callback support added in 60c4f031 is also currently inert, because it guards on __GCC__ — which no compiler defines — rather than __GNUC__. That one is #1349. I would be happy to follow up with a MinGW CI job once these are in; it would be red today, so it should land after the fixes rather than before.

Happy to split this into two commits, or reword, if you would prefer.

Both can be the very first mimalloc call in a process. When they are, the main heap
does not exist yet: `_mi_heap_new_for_subproc` allocates from a NULL
`subproc->heap_main`, and `mi_subproc_new`'s `_mi_meta_zalloc` allocates out of the
parent's main heap, which is likewise not there.

On platforms with a library constructor something has always initialized the
allocator earlier, which is why this only shows up on Windows. It is the same class
as issue microsoft#1341 (`free(NULL)` before init).

`mi_thread_init()` is the same idempotent bootstrap the allocation path already
performs, and it calls `mi_process_init()` in turn, so both call sites just need to
do what a first `malloc` would have done.

Verified on this commit (1f06f69), MinGW-w64 GCC 12.2 x86_64, configured exactly
as .github/workflows/test.yaml does for its `basic` entry
(-DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON):

  before:  67% tests passed, 2 tests failed out of 6
             3 - test-stress-heaps     (Exit code 0xc0000409)
             4 - test-stress-subprocs  (Exit code 0xc0000409)

  after:  100% tests passed, 0 tests failed out of 6

0xc0000409 is Windows fail-fast, so these are hard aborts rather than assertion
failures. Configure and build are clean in both cases; the difference is entirely
at runtime.

Note these two tests are in the repository already and pass under MSVC -- there is
simply no MinGW job in CI, so nothing exercises the configuration where the missing
bootstrap is reachable.

Co-Authored-By: Claude <noreply@anthropic.com>
@zackees

Copy link
Copy Markdown
Contributor Author

agree @microsoft-github-policy-service agree

@zackees

Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree

Zachary Vorhies (zackees) added a commit to zackees/mimalloc-pprof that referenced this pull request Aug 2, 2026
…158)

Cut from upstream/dev3 tip and verified there in upstream's own `basic`
configuration (Debug, MI_DEBUG_FULL=ON) under MinGW-w64 GCC 12.2:

  before:  67% tests passed, 2 failed of 6  (test-stress-heaps,
           test-stress-subprocs, both Exit code 0xc0000409)
  after:  100% tests passed, 0 failed of 6

Two mi_thread_init() calls, in mi_heap_new_in_arena and mi_subproc_new. Sent
without the #128 B1 subproc-heap-leak fix that sits adjacent in our tree, so the
PR is one concern.

The PR also flags #1349 and offers the MinGW CI job as a follow-up, stating that it
would be red today and should therefore land after the fixes rather than before --
the sequencing recorded here last iteration.

Co-authored-by: Claude <noreply@anthropic.com>
@daanx
Daan (daanx) merged commit 10c2c3b into microsoft:dev3 Aug 2, 2026
1 check passed
@daanx

Copy link
Copy Markdown
Collaborator

Thank you.

@res2k

Copy link
Copy Markdown
Contributor

I wonder, if 4cca633 fixes GCC detection on MinGW, why is this still needed?
The assumption prim.c makes is that the "TLS callback using special data sections" works on both MinGW and MSVC.
Is this not the case?
Because if thread init works on MinGW now as well, the changes here would've been unnecessary...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants