fix(spawnSync): throw instead of segfaulting when event-loop creation fails - #35033
Open
robobun wants to merge 4 commits into
Open
fix(spawnSync): throw instead of segfaulting when event-loop creation fails#35033robobun wants to merge 4 commits into
robobun wants to merge 4 commits into
Claude / Claude Code Review
completed
Jul 22, 2026 in 22m 27s
Code review found 2 potential issues
Found 2 candidates, confirmed 2. See review comments for details.
Details
| Severity | Count |
|---|---|
| 🔴 Important | 0 |
| 🟡 Nit | 2 |
| 🟣 Pre-existing | 0 |
| Severity | File:Line | Issue |
|---|---|---|
| 🟡 Nit | src/runtime/api/bun/js_bun_spawn_bindings.rs:1081-1087 |
Windows: extra_fds uv::Pipe allocations leak on the new loop-init-failed early return |
| 🟡 Nit | packages/bun-usockets/src/eventing/epoll_kqueue.c:806-808 |
macOS async cleanup leaks a dead-name right after dropping the receive right |
Annotations
Check warning on line 1087 in src/runtime/api/bun/js_bun_spawn_bindings.rs
claude / Claude Code Review
Windows: extra_fds uv::Pipe allocations leak on the new loop-init-failed early return
On Windows, this new early return leaks any `Box<uv::Pipe>` allocations sitting in `extra_fds` (populated by `as_spawn_option()` for stdio slots ≥ 3) — `WindowsStdio` deliberately has no `Drop`, and `spawn_options.deinit()` (which would iterate `extra_fds` and call `.deinit()`) hasn't been reached yet. This is heap-only (~`sizeof(uv_pipe_t)` per slot, never `uv_pipe_init`'d so no OS handle) and the same pattern already exists on several pre-existing early returns in this function, so it needn't
Check warning on line 808 in packages/bun-usockets/src/eventing/epoll_kqueue.c
claude / Claude Code Review
macOS async cleanup leaks a dead-name right after dropping the receive right
On the `mach_port_set_attributes` failure path, `mach_port_mod_refs(..., MACH_PORT_RIGHT_RECEIVE, -1)` destroys the port but the send right added by `mach_port_insert_right` is converted to a dead-name entry that persists in the task's port name table (the code comment even says so). Add `mach_port_deallocate(self, cb->port);` after the `mod_refs` call to release it — same as `us_internal_async_close` does for the send right on the normal-close path. Essentially-unreachable trigger, but this blo
Loading