Skip to content

abi: reserve 48 KiB for valid fork continuations#954

Open
brandonpayton wants to merge 1 commit into
mainfrom
fix/fork-continuation-buffer-48k
Open

abi: reserve 48 KiB for valid fork continuations#954
brandonpayton wants to merge 1 commit into
mainfrom
fix/fork-continuation-buffer-48k

Conversation

@brandonpayton

@brandonpayton brandonpayton commented Jul 15, 2026

Copy link
Copy Markdown
Member

Why

When a process calls fork, Kandelo saves enough instrumented WebAssembly call-frame data to resume the child at the same point. That saved data is the fork continuation, and the reserved linear-memory region that holds it is the fork save buffer. KiB means 1,024 bytes.

Kandelo's truthful fork-overrun guard is rejecting valid real application continuations because every main-thread, pthread, and side-module fork save buffer is fixed at 16 KiB.

Measured production paths already exceed that reserve:

Consumer Required continuation bytes Current reserve
Homebrew dispatcher 20,012 16,384
Homebrew /usr/bin/brew alias launcher 29,212 16,384
GTK/GLib launch 21,544 16,384

The existing guard correctly prevents those writes from becoming channel or control-state corruption, but Homebrew and GTK cannot complete valid forks at the current capacity.

What changed

  • Increase the shared fork save-buffer constant from 16 KiB to 48 KiB for main workers, pthread workers, and fork-capable side modules.
  • Keep the buffer within its existing 64 KiB scratch page, leaving 16 KiB below it for host-owned control metadata such as the process-wide dlopen archive anchor.
  • Keep the existing truthful overrun detector for continuations larger than 48 KiB.
  • Replace hardcoded 16 KiB assumptions in runtime test harnesses with the generated shared constant.
  • Pin all three measured application continuations in the focused capacity test.
  • Record the incompatible layout as ABI 40 and regenerate the ABI snapshot plus generated C and TypeScript constants.

This is a platform capacity correction, not a Homebrew-specific bypass. All ABI-bound programs, package archives, and VFS images must be rebuilt through the normal ABI 40 release path; this source PR must not be merged separately from that train.

When the ABI 40 integration batch combines this change with #944, it must also update #944's bootstrap probe and documentation to require a successful brew --version instead of accepting the historical ABI 39 reserve failure. Those files do not exist on this source branch because #944 has not merged.

Validation

Run through scripts/dev-shell.sh on exact commit 27b37930f3a1ebc57017973d3cd74c6ddedce415 / tree dacd6b77055ad3732d1219eeb80212b8dac62970:

  • scripts/check-abi-version.sh passed and confirmed the ABI bump plus synchronized snapshot/generated bindings;
  • the focused fork-save overrun suite passed 9/9, including the measured Homebrew dispatcher, alias-launcher, and GTK continuation sizes;
  • git diff --check origin/main...HEAD passed.

The complete fork-instrument suite passed on this exact head (186 tests).

Host declaration generation was attempted on the predecessor, but the isolated source worktree has no installed host/node_modules, so tsup was unavailable. Full host, browser, libc, POSIX, Sortix, package-universe, and rebuilt Homebrew bootstrap validation is intentionally assigned to the broad ABI 40 batch that absorbs this exact source commit.

@brandonpayton brandonpayton force-pushed the fix/fork-continuation-buffer-48k branch from d0aa42d to 1b942fd Compare July 15, 2026 20:09
The fixed 16 KiB save buffer rejects valid wide fork call chains: the Homebrew launcher needs 20,012 bytes and GTK/GLib needs 21,544 bytes. Reserve 48 KiB within the existing 64 KiB main and pthread scratch pages, and apply the same bound to side modules.

Publish the incompatible address/layout change as ABI 40, regenerate the snapshot and generated host/libc constants, and keep truthful overrun detection above the new capacity.
@brandonpayton brandonpayton force-pushed the fix/fork-continuation-buffer-48k branch from 1b942fd to 27b3793 Compare July 16, 2026 00:34
@brandonpayton

Copy link
Copy Markdown
Member Author

The automatic exact-head staging run was intentionally cancelled after preflight. This source PR changes ABI 40, but it is not the merge unit: rebuilding its incomplete package universe would be discarded when the final ABI 40 batch adds the remaining reviewed source commits. The final batch must run the one authoritative package-universe, Node/browser, conformance, and Homebrew bootstrap build.

@github-actions

Copy link
Copy Markdown

Phase B-1 matrix build status — pr-954-staging

ABI v40. 0 built, 71 failed, 71 total.

Package Arch Status Sha
icu wasm32 failed
libcurl wasm32 failed
libcxx wasm32 failed
libcxx wasm64 failed
libiconv wasm32 failed
libpng wasm32 failed
libxml2 wasm32 failed
libzip wasm32 failed
openssl wasm32 failed
openssl wasm64 failed
sqlite wasm32 failed
sqlite wasm64 failed
zlib wasm32 failed
zlib wasm64 failed
bc wasm32 failed
bzip2 wasm32 failed
coreutils wasm32 failed
curl wasm32 failed
dash wasm32 failed
diffutils wasm32 failed
dinit wasm32 failed
fbdoom wasm32 failed
file wasm32 failed
findutils wasm32 failed
gawk wasm32 failed
git wasm32 failed
grep wasm32 failed
gzip wasm32 failed
hello wasm32 failed
kandelo-sdk wasm32 failed
kernel wasm32 failed
less wasm32 failed
lsof wasm32 failed
m4 wasm32 failed
make wasm32 failed
mariadb wasm32 failed
mariadb wasm64 failed
modeset wasm32 failed
msmtpd wasm32 failed
nano wasm32 failed
ncurses wasm32 failed
netcat wasm32 failed
nginx wasm32 failed
php wasm32 failed
posix-utils-lite wasm32 failed
ruby wasm32 failed
sed wasm32 failed
spidermonkey wasm32 failed
tar wasm32 failed
tcl wasm32 failed
unzip wasm32 failed
userspace wasm32 failed
vim wasm32 failed
wget wasm32 failed
xz wasm32 failed
zip wasm32 failed
zstd wasm32 failed
bash wasm32 failed
mariadb-test wasm32 failed
mariadb-vfs wasm32 failed
mariadb-vfs wasm64 failed
nethack wasm32 failed
node wasm32 failed
spidermonkey-node wasm32 failed
vim-browser-bundle wasm32 failed
nethack-browser-bundle wasm32 failed
rootfs wasm32 failed
shell wasm32 failed
lamp wasm32 failed
node-vfs wasm32 failed
wordpress wasm32 failed

Auto-generated; replaced on each push. Raw data in the publish-status workflow artifact.

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.

1 participant