fix(release): pin Linux builders to ubuntu-22.04 to avoid glibc 2.39 segfault#135
fix(release): pin Linux builders to ubuntu-22.04 to avoid glibc 2.39 segfault#135emal-avala merged 1 commit intomainfrom
Conversation
…segfault (#134) Release binaries built on ubuntu-latest (Ubuntu 24.04, glibc 2.39) import `pidfd_spawnp` and `pidfd_getpid` as weak GLIBC_2.39 symbols. On systems with glibc < 2.39 (Ubuntu 22.04, Debian 12, RHEL 9, ...) these resolve to NULL and the first tokio subprocess spawn — e.g. session_env's git detection at startup — segfaults with "Segmentation fault (core dumped)". Pin the Linux x86_64 and aarch64 builders to ubuntu-22.04 (glibc 2.35) so the published binaries remain compatible with the large majority of modern distros that haven't yet shipped glibc 2.39. Fixes #134.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Self-review (deep)ScopeTwo Safety checklist
Root cause verificationConfirmed by inspecting the v0.16.0 linux-x86_64 artifact locally: These weak symbols come from libc-crate / tokio's posix_spawn path. They start the process fine on older-glibc systems but segfault (NULL deref) when called. Known limitations (called out in PR body)
Suggested follow-up (not blocking)Add a regression check in the release workflow so this class of bug can't silently recur if a future dependency pulls in new weak symbols: - name: Assert binary has no newer-glibc weak symbols
if: contains(matrix.target, 'linux')
run: |
if objdump -T target/${{ matrix.target }}/release/agent | grep -E 'GLIBC_2\.3[6-9]|GLIBC_2\.[4-9][0-9]'; then
echo "::error::Binary imports newer-glibc symbols; compat floor broken"
exit 1
fiVerdictSafe to merge. Minimal, targeted, well-explained. No risk of breaking existing users; fixes a clear segfault path for the large majority of non-Ubuntu-24.04 Linux users once the next release ships. |
Summary
Fixes #134 —
Segmentation fault (core dumped)immediately after runningagenton a freshly installed binary.Root cause
The release workflow builds Linux binaries on
ubuntu-latest, which is currently Ubuntu 24.04 (glibc 2.39). Inspecting the publishedagent-linux-x86_64binary shows two weak imports fromGLIBC_2.39:These come from tokio's process spawning path in modern Rust stdlib. They're weak references — the dynamic linker lets the program start even if they're missing — but when the program calls them on a system with glibc < 2.39, the symbol resolves to
NULLand the call segfaults.agenthits this path almost immediately after launch:main()→SessionEnvironment::detect()→git::is_git_repo()→tokio::process::Command::new("git").status()→posix_spawnp-family call →pidfd_spawnp→ NULL deref → SIGSEGV.Distros affected (glibc < 2.39):
Fix
Pin the Linux x86_64 and aarch64 release builders to
ubuntu-22.04(glibc 2.35). The resulting binary no longer imports GLIBC_2.39 symbols and runs cleanly on all of the distros above. Users who need older-glibc compatibility (Ubuntu 20.04 / glibc 2.31) can stillcargo install agent-code; moving tocargo-zigbuildfor an even wider compat floor is a reasonable follow-up but out of scope here.macOS and Windows builders are untouched.
Test plan
GLIBC_2.39imports (pidfd_spawnp,pidfd_getpid).session_env::detect→git::is_git_repo→tokio::process::Command) that triggers the segfault on glibc < 2.39 runs at startup on every invocation.ubuntu-22.04is a supported GitHub Actions runner (actions/runner-images).objdump -T agent | grep GLIBC_2.3[6-9]on the new release artifact — should show noGLIBC_2.39imports, highest symbol should beGLIBC_2.34(pthread) orGLIBC_2.35.docker run --rm -it ubuntu:22.04) —agent --versionandagent(setup wizard) should run without segfaulting.🤖 Generated with Claude Code