Skip to content

chore: bump libsui to 0.16.0 - #35467

Merged
littledivy merged 1 commit into
denoland:mainfrom
littledivy:fix/libsui-0.16-bss-desktop
Jun 24, 2026
Merged

chore: bump libsui to 0.16.0#35467
littledivy merged 1 commit into
denoland:mainfrom
littledivy:fix/libsui-0.16-bss-desktop

Conversation

@littledivy

Copy link
Copy Markdown
Member

Bumps libsui 0.15.0 → 0.16.0.

Why

Fixes the deno desktop "no window" hang on Linux (#35381).

deno desktop embeds the app's metadata into the compiled runtime .so via libsui::Elf::append. In 0.15.0 append placed the .note.sui section at a virtual address derived from its file offset, ignoring that a trailing .bss (SHT_NOBITS) makes the carrier PT_LOAD's memory image larger than its file image. On a binary whose .bss is large enough to cross the placement boundary — e.g. the CI-built libdenort.so (glibc-2.27 sysroot) — the note's mapped range landed inside .bss. At startup the zero-initialized globals aliased the embedded metadata:

  • find_section read corrupted bytes → control character (\^@-\^_) found while parsing a string, or
  • a futex deadlock during dlopen static init → hang, no window, before Deno.serve ran.

Small binaries (a local debug libdenort.so) have a different .bss layout that doesn't cross the boundary, which is why the DENORT_DESKTOP_BIN=…/libdenort.so workaround in the issue worked.

Fix (in libsui 0.16.0)

Regression test in libsui inflates a fixture's .bss and asserts the note's mapped range overlaps no allocated section (fails on 0.15.0, passes on 0.16.0).

No deno code changes — the libsui API is unchanged.

Note: the earlier libc++abi: __cxa_guard_acquire crash from the same issue was already fixed in #35424.

Closes #35381

Fixes the `deno desktop` no-window hang on Linux. libsui's `Elf::append`
(used to embed app metadata into the compiled runtime .so) placed the
`.note.sui` section at a virtual address derived from its file offset,
ignoring that a trailing `.bss` (SHT_NOBITS) makes the carrier segment's
memory image larger than its file image. On binaries with a large enough
`.bss` (e.g. the CI-built libdenort.so) the note's mapped range landed
inside `.bss`; at startup the zero-initialized globals aliased the embedded
metadata and corrupted it, so the runtime read garbage ("control character
found while parsing a string") or deadlocked before `Deno.serve` ran.

libsui 0.16.0 places the note past the carrier segment's whole memory image
and appends in-place to preserve RELR relocations.

Closes denoland#35381
@littledivy
littledivy merged commit ab8c254 into denoland:main Jun 24, 2026
136 checks passed
littledivy added a commit that referenced this pull request Jul 2, 2026
…35699)

Fixes #35633

## Problem

Standalone binaries produced by `deno compile` segfault (exit 139) after
`eu-strip` runs over them — which `flatpak-builder` does automatically
during a flatpak build. Regression in Deno 2.9, bisected to the libsui
0.16.0 bump (#35467).

## Root cause

libsui's in-place `Elf::append` (new in 0.16.0) relocates the program
header table past the original EOF, into the file gap just before the
appended note. `eu-strip` (elfutils, as run by flatpak-builder) lays the
stripped output out itself with `ELF_F_LAYOUT` and zero-fills every file
gap that falls between two allocated sections. With only a note-sized
`.note.sui` section past that gap, eu-strip treats the relocated program
header table as dead space and zeroes it → all-NULL program headers →
segfault on exec.

## Fix

libsui 0.16.1 (denoland/sui#75) covers the relocated program header
table with a dedicated allocated `.sui.phdrs` section so section-based
strip tools preserve it. This bumps the dependency and adds a spec test
that `eu-strip`s a compiled binary and asserts it still runs (skips
gracefully where `eu-strip` isn't installed).

## Verification

Reproduced and fixed against the exact flatpak toolchain (elfutils
**0.193**, built from source) on Linux x86_64:

- real `deno 2.9.0` compiled binary + eu-strip 0.193 (flatpak flags) →
**segfault 139**; with 0.16.1 → **runs**
- every binary shape (PIE+RELR, plain PIE, non-PIE, large `.bss`,
section-header-stripped, fully stripped) × eu-strip 0.193 & 0.190 →
runs, program headers intact
- payload sizes 1 B – 1 MB → payload still recoverable after strip
- real denort 2.9.0 base → program headers intact after strip
- binutils `strip` note-survival preserved (unchanged from 0.16.0)
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.

deno desktop no window appears (+ feedback)

2 participants