Skip to content

fix: gate -lopfs.js behind pthreads to fix OPFS crash#360

Merged
adsharma merged 1 commit intoLadybugDB:mainfrom
kbatchu:fix/wasm-opfs-pthread-pairing
Apr 3, 2026
Merged

fix: gate -lopfs.js behind pthreads to fix OPFS crash#360
adsharma merged 1 commit intoLadybugDB:mainfrom
kbatchu:fix/wasm-opfs-pthread-pairing

Conversation

@kbatchu
Copy link
Copy Markdown

@kbatchu kbatchu commented Apr 2, 2026

Summary

Fixes the OPFS UNREACHABLE crash at opfs_backend.cpp:292 by ensuring -lopfs.js is only linked when pthreads are enabled.

  • Move -lopfs.js and OPFS exported functions (_wasmfs_create_opfs_backend, _wasmfs_create_directory) inside the NOT __SINGLE_THREADED__ guard
  • Single-threaded browser builds still get WasmFS (in-memory) but no longer link the broken OPFS backend
  • Multi-threaded browser builds get OPFS with correct pthread pairing

Root cause

-lopfs.js is linked unconditionally in the browser WasmFS build (the else() branch), but -pthread is only added when NOT __SINGLE_THREADED__. The Emscripten OPFS JS backend internally calls _emscripten_proxy_finish, which is only defined with pthreads. Without it, wasmfsOPFSProxyFinish compiles as a no-op, so at runtime the OPFS backend reads childType=0 and hits:

Unexpected child type
UNREACHABLE executed at opfs_backend.cpp:292

What changes

CMakeLists.txt — In the BUILD_WASM / browser-WasmFS branch:

Before After
-lopfs.js linked unconditionally -lopfs.js only linked when NOT __SINGLE_THREADED__
OPFS exports always present OPFS exports only in multi-threaded build
allocateUTF8 always exported allocateUTF8 only exported when OPFS is available

The companion JS-side fixes (WasmFS C API usage, runtime detection, OPFS tests) are already merged in ladybug-wasm — see commits 6305367 and c495097.

Test plan

  • Multi-threaded browser build (SINGLE_THREADED=false): verify OPFS mounts and persists data
  • Single-threaded browser build (SINGLE_THREADED=true): verify build succeeds, mountOpfs() returns a clear error instead of crashing
  • Node.js build (WASM_NODEFS=true): verify no regression (unaffected code path)
  • WASM test build (BUILD_TESTS=true): verify no regression (NODERAWFS path)

Ref: #305

-lopfs.js internally uses _emscripten_proxy_finish, which is only
defined when pthreads are enabled. Linking it without -pthread causes
wasmfsOPFSProxyFinish to compile as a no-op, so at runtime the OPFS
backend reads childType=0 and hits UNREACHABLE at
opfs_backend.cpp:292.

Move -lopfs.js and the OPFS exported functions inside the
NOT __SINGLE_THREADED__ guard so they are only linked when -pthread
is also present. The single-threaded browser build still gets WasmFS
(in-memory) but no longer links the broken OPFS backend.

Ref: LadybugDB#305

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@adsharma adsharma merged commit 3aebfbb into LadybugDB:main Apr 3, 2026
4 checks passed
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.

2 participants