#48109·servo

servoshell release build segfaults (0xC0000005) on Wikipedia; reproduces on pure upstream, independent of opt-level, fixed by enabling LTO

Author: isaaliaCreated Sep 15, 2026Updated Sep 16, 2026

Describe the bug:

servoshell release builds (--no-default-features --features "bundled,default_web_features,max_log_level,js_jit", so no multiprocess) segfault loading https://www.wikipedia.org0xC0000005 (STATUS_ACCESS_VIOLATION) on Windows, zero log output, no Windows Error Reporting event (servoshell's crash handler is currently a no-op on Windows — separate issue, will file). Debug builds of the identical checkout load the same URL without issue.

Isolation done before filing (each build/repro from a clean, standalone directory — exe + libEGL.dll/libGLESv2.dll only, no dev-environment dependency):

Profile Settings vs. plain release Crashes?
release (baseline) opt-level=3, lto=false, debug-assertions=false, overflow-checks=false Yes
medium (built-in) inherits dev — opt-level=2, but ALSO debug-assertions=true, overflow-checks=true No — but conflates 3 variables, not conclusive alone
release-opt2 (custom, isolates opt-level only) opt-level=2, everything else same as release Yes — still crashes
release-lto (custom, isolates LTO only) lto = true, everything else same as release No — loads successfully

So: neither opt-level nor debug-assertions/overflow-checks alone explain it via the release-opt2 result — lowering optimization alone does not avoid the crash. Enabling LTO does. This points at the crash being sensitive to something LTO's cross-crate inlining/codegen changes (or removes) — possibly a UB pattern in generated code that opt-level=3-without-LTO exposes and opt-level=3-with-LTO happens not to, similar in flavor to #41190 (mozjs Handle aliasing UB, already fixed upstream — confirmed our checkout has that fix; this is a different bug).

I have not attempted to isolate further (e.g. bisecting which crate's codegen the LTO pass changes, or disabling js_jit to separate JIT/GC-specific corruption from general codegen corruption) — filing now with what's conclusively isolated rather than continuing to guess blind, per your own contributing guidance about not chasing memory-safety bugs without a debugger. Happy to run further isolation if it's useful and someone can point at where to look.

To Reproduce:

  1. cargo build --release -p servoshell --no-default-features --features "bundled,default_web_features,max_log_level,js_jit"
  2. Copy libEGL.dll/libGLESv2.dll from the mozangle-* build script output dir next to the built servoshell.exe (a separate, known gap — build.rs doesn't do this automatically for any profile)
  3. ./servoshell.exe https://www.wikipedia.org
  4. Segfaults, 0xC0000005, no console output, no WER event.

Workaround in use downstream: lto = true on the release profile.

Platform: Windows 11, rustc/toolchain 1.97.1, LLVM 22.1.6 (this repo's pinned rust-toolchain.toml), NVIDIA RTX 5080 (real GPU/driver, not a software-rendering or headless environment).