Skip to content

fix(sys): mimalloc3 v3.5.1 + fix for the process-init thread's thread-done hook - #97

Merged
Brooooooklyn merged 1 commit into
mainfrom
fix/mimalloc3-first-thread-done
Sep 4, 2026
Merged

fix(sys): mimalloc3 v3.5.1 + fix for the process-init thread's thread-done hook#97
Brooooooklyn merged 1 commit into
mainfrom
fix/mimalloc3-first-thread-done

Conversation

@Brooooooklyn

@Brooooooklyn Brooooooklyn commented Sep 4, 2026

Copy link
Copy Markdown
Member

Background

mimalloc v3.5.0 (shipped in libmimalloc-sys2 0.1.61 / mimalloc-safe 0.1.65 by #92) never associates the process-init thread's theap with the pthread thread-done key. If the first thread that touches the allocator exits — a Node.js worker_threads worker that loads the addon first, then exits — _mi_thread_done never runs for it, its theap stays registered with its thread id, and the next thread that reuses that pthread TCB aborts in debug builds:

mimalloc: assertion failed: at "src/init.c":327, _mi_thread_init_with_heap
  assertion: "theap==NULL"

Release builds skip the assert but leak the dead thread's theap and pages. Linux only in practice (macOS enables MI_TLS_RECURSE_GUARD, which makes the new thread adopt the stale theap). Upstream culprit: microsoft/mimalloc@5d9cb381 ("remove static main theap and tld"); v3.4.5 was the last good tag. Reported upstream with the fix: microsoft/mimalloc#1393. Found via rolldown/rolldown#10268 CI (watch debounce timers survive a worker-first registrant that exited), which pinned mimalloc-safe = "=0.1.64" as a stopgap.

Changes

Verification (Docker linux/arm64, node 22, debug + release builds of example/ with --features v3)

tree Node worker-first flow (1 / 64 / 64+4 concurrent workers) Rust std threads reusing the dead TCB release cargo test --features v3 sys-test
v3.5.0 / v3.5.1 unfixed assertion + SIGABRT assertion + SIGABRT OK (leaks)
1e5d14ca OK OK OK 6/6 251/251

Bisect over v3.4.5..v3.5.0 (7 steps) isolates 5d9cb381. The v2 line (c_src/mimalloc v2.5.0) does not have the gap and passes the same flow.

Once released, rolldown can drop its =0.1.64 pin.

🤖 Generated with Claude Code

https://claude.ai/code/session_01T34fMrYCf2V13Mg8BKmnda


Note

High Risk
Touches process-wide allocator and per-thread teardown in native code; wrong behavior can cause crashes or leaks in multi-threaded hosts (e.g. Node worker_threads), though scope is limited to the v3 submodule.

Overview
Repoints the mimalloc3 git submodule from microsoft/mimalloc (dev3) to napi-rs/mimalloc on branch fix/first-thread-done, matching the prior fork-based workflow used for targeted allocator fixes.

That branch carries mimalloc v3.5.1 plus a small src/init.c change so the process-init thread’s default heap is registered with the pthread thread-done hook. Without it, a worker thread that is the first allocator user and then exits can leave a stale heap on reused pthread TCBs (debug abort in _mi_thread_init_with_heap, leaks in release on Linux).

No Rust build.rs or crate source changes in this diff; consumers get the fix via the updated vendored mimalloc3 tree.

Reviewed by Cursor Bugbot for commit dd53da2. Bugbot is set up for automated code reviews on this repo. Configure here.

…-done hook

mimalloc v3.5.0 (shipped by #92) never associates the process-init
thread's theap with the pthread thread-done key. When the first thread
that touches the allocator exits (a Node.js worker that loads the addon
first), `_mi_thread_done` never runs for it, its theap stays registered
with its thread id, and the next thread that reuses that pthread TCB
aborts in debug builds:

  mimalloc: assertion failed: at "src/init.c":327, _mi_thread_init_with_heap
    assertion: "theap==NULL"

Release builds skip the assert but leak the dead thread's theap and
pages. Upstream culprit: microsoft/mimalloc@5d9cb381; reported with the
fix as microsoft/mimalloc#1393.

Point the `mimalloc3` submodule at the napi-rs/mimalloc fork branch
`fix/first-thread-done` = upstream v3.5.1 + the 11-line src/init.c fix
(same approach as #71), until upstream ships it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T34fMrYCf2V13Mg8BKmnda
@cursor

cursor Bot commented Sep 4, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_fceb089e-55a8-4416-8113-a18f533d39a9)

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-04T15:15:48.078684Z dd53da2 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@Brooooooklyn
Brooooooklyn merged commit 6aba2ab into main Sep 4, 2026
21 checks passed
@Brooooooklyn
Brooooooklyn deleted the fix/mimalloc3-first-thread-done branch September 4, 2026 15:21
@github-actions github-actions Bot mentioned this pull request Aug 24, 2026
Brooooooklyn pushed a commit that referenced this pull request Sep 4, 2026
## 🤖 New release

* `libmimalloc-sys2`: 0.1.61 -> 0.1.62 (✓ API compatible changes)
* `mimalloc-safe`: 0.1.65 -> 0.1.66 (✓ API compatible changes)

<details><summary><i><b>Changelog</b></i></summary><p>

## `libmimalloc-sys2`

<blockquote>

## [0.1.62] - 2026-09-04

### Bug Fixes

- *(sys)* Mimalloc3 v3.5.1 + fix for the process-init thread's
thread-done hook
([#97](#97))

### Chore

- *(deps)* Update mimalloc (v2) submodule to v2.5.1
([#98](#98))
</blockquote>

## `mimalloc-safe`

<blockquote>

## [0.1.66] - 2026-09-04

### Bug Fixes

- *(sys)* Mimalloc3 v3.5.1 + fix for the process-init thread's
thread-done hook
([#97](#97))

### Chore

- *(deps)* Update dependency @napi-rs/cli to v3.9.0
([#94](#94))
- *(deps)* Update dependency @emnapi/core to v2.0.0-alpha.5
([#95](#95))
- *(deps)* Update dependency @emnapi/runtime to v2.0.0-alpha.5
([#96](#96))
- *(deps)* Update mimalloc (v2) submodule to v2.5.1
([#98](#98))
</blockquote>


</p></details>

---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@github-actions github-actions Bot mentioned this pull request Sep 4, 2026
Brooooooklyn pushed a commit that referenced this pull request Sep 4, 2026
## 🤖 New release

* `libmimalloc-sys2`: 0.1.61 -> 0.1.62
* `mimalloc-safe`: 0.1.65 -> 0.1.66

<details><summary><i><b>Changelog</b></i></summary><p>

## `libmimalloc-sys2`

<blockquote>

## [0.1.62] - 2026-09-04

### Bug Fixes

- *(sys)* Mimalloc3 v3.5.1 + fix for the process-init thread's
thread-done hook
([#97](#97))

### Chore

- *(deps)* Update mimalloc (v2) submodule to v2.5.1
([#98](#98))
</blockquote>

## `mimalloc-safe`

<blockquote>

## [0.1.66] - 2026-09-04

### Bug Fixes

- *(sys)* Mimalloc3 v3.5.1 + fix for the process-init thread's
thread-done hook
([#97](#97))

### Chore

- *(deps)* Update dependency @napi-rs/cli to v3.9.0
([#94](#94))
- *(deps)* Update dependency @emnapi/core to v2.0.0-alpha.5
([#95](#95))
- *(deps)* Update dependency @emnapi/runtime to v2.0.0-alpha.5
([#96](#96))
- *(deps)* Update mimalloc (v2) submodule to v2.5.1
([#98](#98))
</blockquote>


</p></details>

---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Brooooooklyn added a commit to rolldown/rolldown that referenced this pull request Sep 4, 2026
0.1.66 ships mimalloc v3.5.1 plus the fix for the process-init thread's
thread-done hook (see microsoft/mimalloc#1393, napi-rs/mimalloc-safe#97),
so the `=0.1.64` stopgap from 4855394 is no longer needed. Cargo.lock:
mimalloc-safe 0.1.64 -> 0.1.66, libmimalloc-sys2 0.1.60 -> 0.1.62.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T34fMrYCf2V13Mg8BKmnda
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.

1 participant