0.13.5 --- a large allocation is a mapping, and a mapping is whole pages - #34
Merged
Conversation
musl's allocator obtains an allocation of MMAP_THRESHOLD bytes or more as a mapping of n + IB + UNIT bytes and uses it up to the end of its last page: the block starts up to a page into the slot and the slot's footer is written just below the page's end. The port's mmap obtained exactly the length asked for, so where kal_alloc hands out that length and no more (the process heap on Windows) the footer and up to a page of the block lay over the next heap block's header. A std::string grown past 196,607 bytes ended the program under Wine; on windows-2022 lsp-mcpp's conformance runner stopped with an access violation reading a build tree. SYS_mmap and SYS_munmap round the length up to whole pages. examples/malloc-large observes the tail of a mapping, blocks grown from half the threshold to eight megabytes, and realloc across the threshold; CI runs it on every row.
This was referenced Sep 14, 2026
Sunrisepeak
added a commit
to Sunrisepeak/lsp-mcpp-private
that referenced
this pull request
Sep 14, 2026
On Windows an allocation of 131,052 bytes or more wrote past its heap block: musl uses a mapping to the end of its last page and the port had obtained only the length asked for (mcpplibs/openkal-musl#34, mcpplibs/openkal-llvm-runtime#21, mcpp-index#424 and #425). The conformance runner stopped on build trees with it, and the server would have on any large file or message.
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.
Every program on Windows that allocated 131,052 bytes or more wrote past the memory it had obtained. The overrun reached up to a page beyond the block, into the next heap block's header. The program went on until the heap next walked there, then stopped with an access violation or ended without a word.
musl's allocator obtains such an allocation as a mapping of its own,
mmap(n + IB + UNIT), and uses the mapping up to the end of its last page:get_stride: the slot of an individually mapped allocation ismaplen * 4096 - UNITbytes, wheremaplenis the length rounded up to pages.enframe: the block starts at a cycling offset of up toslackunits into the slot, so up to a page past the start.set_size: the slot's footer,*(uint32_t *)(end - 4), is written just below the end of the last page.On Linux those bytes exist, because the kernel maps whole pages. This port's
do_mmapobtainedkal_alloc(len, 4096)for exactlylen. Wherekal_allochands out that length and no more, which is the process heap on Windows, the footer and the tail of the block lay beyond the allocation.Measured under Wine, x86_64-windows-gnu, both profiles:
Found through lsp-mcpp. On windows-2022 its conformance runner, a release build over openkal-llvm-runtime 0.9.5, stopped with an access violation while reading a build tree with a file of about 200 KB.
port/src/okm_syscall.c:SYS_mmapandSYS_munmapround the length up to whole pages, and a length that cannot be rounded isENOMEM.examples/malloc-largeobserves three things, and CI runs it on every row:reallocacross the threshold in both directions.Measured locally: the probe passes on x86_64 Linux, and on x86_64-windows-gnu under Wine in dev and release. With the change, the string and
operator newpatterns above complete, as does a 300 KB read throughstd::istreambuf_iterator. Without it, the probe fails and then faults.