mimalloc icon indicating copy to clipboard operation
mimalloc copied to clipboard

Mimalloc v3 crash with many short-lived `mi_heap_t` created on different threads in thread pool

Open Jarred-Sumner opened this issue 8 months ago • 2 comments

The crash occurs in mi_free when freeing a 10 KB memory allocation (which was created on the same thread, using the default heap for that thread). It occurs without ASAN enabled and with ASAN enabled (+ MI_DEBUG_FULL=1 & MI_TRACK_ASAN=ON).

I'm not 100% certain this is a bug in Bun or a bug in Mimalloc v3. It does not occur in Mimalloc v1 or Mimalloc v2, but that doesn't rule out the possibility of unknowningly relying on implementation details. Each thread is essentially doing the same memory allocations repeatedly, which probably stress tests Mimalloc v3's memory reuse across threads.

Specifically, this test in Bun https://github.com/oven-sh/bun/blob/c3be6732d1e96c4ef78de09111314f0f6dd49af2/test/regression/issue/09748.test.ts#L215-L235.

Each time transform is called from JavaScript, the source code is cloned (using mi_malloc) and then on another thread, we create a mi_heap_t (via mi_heap_new, so allow_destroy is set to true there) to store all the AST nodes and almost everything else it's doing on that thread except for the output source code being returned. That output source code is passed back to the main thread, and the input source code (created initially via mi_malloc and not via the threadlocal mi_heap_t) gets freed. After about 100 invocations, it crashes in mi_free while freeing the input source code (which calls encoded.deinit which calls mi_free a few layers of indirection later)

https://github.com/oven-sh/bun/blob/c3be6732d1e96c4ef78de09111314f0f6dd49af2/src/bun.js/api/JSTranspiler.zig#L121-L241

I tried to come up with a minimal reproduction outside of Bun and was not successful. ASAN thinks its a use-after-free. ASAN does not show any errors here when using Mimalloc v1 or Mimalloc v2.

Are there any known bugs in the memory reuse code across threads in Mimalloc v3 that could potentially cause this?

Jarred-Sumner avatar Mar 31 '25 09:03 Jarred-Sumner

Hi @Jarred-Sumner -- as I understand it, you call mi_heap_destroy to "free" all temporary allocations in the local heap right? What exactly goes wrong? Can you grab a strack trace? (is this on Linux?).
If you get an access violation can you try to run with MIMALLOC_PURGE_DELAY=-1 to see if it disappears? (there is no known bug with v3 (as of yet :-)), this might be use-after-free but in that case you would think ASAN or Debug Full would catch it?)

daanx avatar Mar 31 '25 21:03 daanx

@Jarred-Sumner Were you able to produce a stacktrace?

reneleonhardt avatar Jun 28 '25 16:06 reneleonhardt