Repository navigation
Conversation
oven-sh/WebKit publishes no baseline (Nehalem) macOS WebKit tarball, so a "baseline" darwin x64 build links the Haswell macOS WebKit. Its bmalloc startup constructors use BMI2/AVX2 and raise SIGILL on pre-Haswell Intel Macs before main() runs, which is why the shipped bun-darwin-x64-baseline crashed at launch on Ivy Bridge (#32511). resolveConfig now fails at configure time with a clear message when a prebuilt baseline macOS build is requested, pointing at the local-WebKit alternative. Local WebKit builds (compiled for Nehalem) and rust-only split builds are exempt. Also corrects the deps/webkit.ts comment that claimed no macOS baseline suffix is emitted.
|
Updated 7:11 AM PT - Jun 19th, 2026
❌ @robobun, your commit c569640 has 1 failures in
🧪 To try this PR locally: bunx bun-pr 32512That installs a local version of the PR into your bun-32512 --bun |
|
Found 1 issue this PR may fix:
🤖 Generated with Claude Code |
|
Good catch, #26872 is the same root cause (SIGILL at launch on a no-AVX2 Intel Mac running |
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
There was a problem hiding this comment.
I didn't find any issues with the guard itself, but this is a release-engineering policy change (it blocks a previously-shipped artifact configuration pending cross-repo WebKit work) and CI is currently red on the musl lanes, so it's worth a human confirming both before merge.
Extended reasoning...
Overview
This PR adds a single configure-time assert() in scripts/build/config.ts:resolveConfig() that refuses to produce a baseline macOS build using prebuilt WebKit, since oven-sh/WebKit publishes no Nehalem macOS tarball and the resulting binary SIGILLs on pre-Haswell Intel Macs. It exempts --webkit=local and rust-only split builds, updates a stale comment in deps/webkit.ts, and adds five regression tests in test/internal/macos-cross-config.test.ts covering the rejection, both exemptions, and that non-baseline macOS / Linux baseline paths are unaffected.
Security risks
None. This is build-configuration logic only — no runtime code, no auth, no untrusted input. The assert reads only the already-resolved config booleans.
Level of scrutiny
Moderate. The code change is small, well-commented, and thoroughly tested, and the bug hunter found nothing. However, it is a release-engineering policy change: it intentionally blocks a build configuration that has previously shipped to users (bun-darwin-x64-baseline), and the PR is explicit that this is only the in-repo half of the fix — the user-facing issue stays open until a Nehalem macOS WebKit is built cross-repo. That trade-off (stop shipping a broken-labelled binary now vs. wait for the full fix) is a maintainer call, not something I should rubber-stamp.
Other factors
Buildkite is currently reporting failures on the x64-musl, x64-musl-baseline, and aarch64-musl build-bun lanes for the head commit. The new assert only fires for baseline && darwin, so it should not affect any musl lane (and two of the three failing lanes aren't baseline at all), which suggests the failures are unrelated infrastructure — but that should be confirmed before merge rather than assumed. The mockToolchain in the test file is missing hostCc/hostCxx keys relative to the Toolchain interface, but that's pre-existing in the file and the spread-with-undefined-fallback in resolveConfig handles it.
|
Thanks. Confirmed the musl lanes are unrelated:
On the policy point: agreed, it's a maintainer call. This PR deliberately only stops Bun from building and shipping a macOS binary mislabeled as "baseline"; it does not restore a working one (that needs a Nehalem macOS WebKit in oven-sh/WebKit). #32511 and #26872 stay open until that lands. The |
|
CI is red again, and on a different darwin lane than the previous run, which confirms darwin test-suite flakiness rather than anything in this diff:
Different lanes, different tests, none of them touching I've used my one retrigger (build #63494) and won't push another to avoid noise. The diff stands on its own for review. As noted in the description, merging is a maintainer call: it's a deliberate release-engineering change (stops building/shipping a macOS binary mislabeled "baseline"), and a binary that actually runs on pre-Haswell Macs additionally needs a Nehalem |
|
Stale PR review: closing. This PR has had no human activity since it was opened on 2026-06-19 and it conflicts with main. The mislabeled build it guards against can no longer exist: #34782 (e550f2c) and oven-sh/WebKit@541f498e4d made every x64 build a single Nehalem build with one WebKit tarball per platform, and #32511 was closed as completed on that basis. On main Reopen if this evidence is wrong. |
Summary
The released
bun-darwin-x64-baselinebinary crashes withSIGILL(illegal instruction) at launch on pre-Haswell Intel Macs (Ivy Bridge, realMacPro6,1, and OCLP setups). The "baseline" macOS x64 binary is not actually baseline: it links the Haswell macOS WebKit prebuilt, which contains BMI2/AVX2 instructions that Ivy Bridge cannot decode.Addresses #32511 and #26872 (same root cause: the shipped
bun-darwin-x64-baselineSIGILLs on no-AVX2 / pre-Haswell Intel Macs). Not auto-closing either: this stops Bun from building and shipping a macOS binary mislabeled as "baseline", but a binary that actually runs on those CPUs additionally needs a Nehalem macOS WebKit built in oven-sh/WebKit (cross-repo, see below).Root cause
The crash fires in a C++ static initializer at process startup (
dyld4::Loader::findAndRunAllInitializersin the backtrace), beforemain()runs. The faulting bytes from the crash report arec4 e2 f1 f7 d0, which decode to the BMI2 instructionshlx(Haswell, 2013+). Ivy Bridge has AVX1 but no BMI1/BMI2, so the CPU raisesSIGILL.Disassembling the shipped
v1.3.14bun-darwin-x64-baselineat the crash offset (0x880A4A) confirms it byte-for-byte:This is a power-of-two size-class computation in a memory allocator's global constructor, i.e. WebKit's
bmallocsetting up its size-class tables at startup.Bun's own code is built correctly for the baseline target:
-march=nehalemforx64 && baseline(scripts/build/flags.ts)-Ctarget-cpu=nehalemfor x64 baseline (scripts/build/rust.ts)But WebKit is a prebuilt download, and oven-sh/WebKit publishes no baseline (Nehalem) macOS tarball. Only
bun-webkit-macos-amd64.tar.gz(Haswell) exists for x64. A "baseline" darwin build therefore links that Haswell WebKit, whosebmalloc/WTFarchives are full of BMI2 (llvm-objdump -d libbmalloc.ashows 313shlx, 297bzhi, etc.), and its startup constructors are the exactfindAndRunAllInitializersframe in the crash.Fix
resolveConfig()now refuses, at configure time, to produce a prebuilt baseline macOS build, with a message that points at the only correct alternative. This replaces the current failure modes (a cryptic 404 onbun-webkit-macos-amd64-baseline.tar.gz, or, if the-baselinesuffix were dropped, silently re-linking the Haswell WebKit, which is how the broken binary shipped) with a clear, actionable error:Exemptions: a local WebKit build (
--webkit=local, compiled for Nehalem viacomputeCpuTargetFlags) andrust-onlysplit builds (which producelibbun_rust.aand never link WebKit) are both allowed. The staledeps/webkit.tscomment that implied a macOS-baselinesuffix is emitted is corrected to point at the guard.This is the in-repo half of the fix: it guarantees Bun can never again silently ship a macOS binary that claims "baseline" but crashes on the CPUs baseline exists to support. It does not, by itself, give pre-Haswell Mac users a working binary.
What a complete fix still needs (cross-repo)
A true baseline macOS binary requires a Nehalem
macos-amd64-baselineWebKit built and published in oven-sh/WebKit. Once that artifact exists, this guard can be relaxed and adarwin/x64/baselinelane added to.buildkite/ci.mjs(which today has no such lane, so the regularbun-darwin-x64is the only macOS x64 artifact, and it is Haswell too). That WebKit build cannot be produced or verified in this environment.Testing
test/internal/macos-cross-config.test.ts(extended) exercisesresolveConfigdirectly with a mock toolchain, so it runs on every host with no build or SDK download:--webkit=localis allowedrust-onlysplit build is allowedbun-webkit-linux-amd64-baseline(the suffix path is untouched)This is a build-configuration fix under
scripts/, so the standardgit stash -- src/ packages/fail-before cannot strip it. Verified manually instead: with the guard removed, the "rejects a prebuilt baseline macOS build" test fails (no throw); with it, all 24 tests pass.bunx tsc --noEmit -p scripts/build/tsconfig.jsonis clean.