fix: bootstrap the library in mi_heap_new and mi_subproc_new - #1351
Merged
Conversation
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>
Contributor
Author
|
agree @microsoft-github-policy-service agree |
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>
18 tasks
Collaborator
|
Thank you. |
Contributor
|
I wonder, if 4cca633 fixes GCC detection on MinGW, why is this still needed? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The defect
mi_heap_newandmi_subproc_newcan 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_subprocallocates from a NULLsubproc->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 callsmi_process_init()in turn. Both call sites just need to do what a firstmallocwould have done.Measurement
On this commit (
1f06f694), MinGW-w64 GCC 12.2 x86_64, configured exactly as.github/workflows/test.yamldoes for itsbasicmatrix entry (-DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON):Before
After
0xc0000409is 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
60c4f031is 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.