deno
df018b90 - fix(desktop): hide bundled libc++ symbols so the desktop runtime can be dlopen'd on Linux (#35424)

Commit
18 days ago
fix(desktop): hide bundled libc++ symbols so the desktop runtime can be dlopen'd on Linux (#35424) Fixes #35381. ## Problem On Linux, `deno desktop` opens no window — the compiled runtime cdylib (`libdenort.so`) aborts at static init before `Deno.serve` runs: ``` libc++abi: __cxa_guard_acquire failed to acquire mutex ``` It's **not** Wayland and **not** backend-specific (cef/webview/raw/hmr all abort). ## Root cause The desktop runtime cdylib statically links V8's own libc++/libc++abi (rusty_v8 `use_custom_libcxx`). A desktop backend `dlopen`s it into a host process that already uses the system **libstdc++**. Without hiding our bundled C++ runtime symbols, ELF interposition binds our internal `__cxa_guard_acquire` (and friends) to the host libstdc++ — whose guard variable layout differs — and the runtime aborts at static-init guard acquisition. macOS is fine because everything there is libc++ (no libstdc++ in the mix). ## Fix Add `-Wl,--exclude-libs,ALL` to the Linux/BSD cdylib link in `cli/rt_desktop/build.rs`. This localizes every static-archive symbol (including the bundled libc++abi), so our `__cxa_*` calls resolve to our own copy. - NAPI/uv symbols stay exported via the existing `--export-dynamic-symbol-list`. - The `laufey_runtime_*` entry points live in this crate's own objects (not an archive), so they remain visible. - macOS link path is untouched. ## Verification On the reporter's environment (Fedora 44 / GNOME Wayland, XWayland path): ```sh cargo build --release -p denort_desktop # -> target/release/libdenort.so # key check — symbol must no longer be exported/interposable: nm -D target/release/libdenort.so | grep __cxa_guard_acquire || echo "OK: not exported" # required exports still present: nm -D target/release/libdenort.so | grep -E "laufey_runtime_(init|start|shutdown)" nm -D target/release/libdenort.so | grep -E "napi_create_string_utf8|uv_default_loop" ``` End-to-end: a `Deno.serve(() => new Response("<h1>Hello, desktop</h1>", {headers:{"content-type":"text/html"}}))` app no longer aborts and the window renders. ## Note If `--exclude-libs,ALL` is considered too broad, a narrower alternative is a version script localizing only the C++ runtime symbols (`__cxa_*`, `__cxxabiv*`, `_ZTI*`, `_ZTV*`, `_ZSt*`, ...) via `-Wl,--version-script=`. Happy to switch if preferred.
Author
Parents
Loading