Skip to content

refactor(fspy): collect execl arguments in the call's bump allocator - #891

Merged
wan9chi merged 1 commit into
mainfrom
fix/fspy-execl-bump-alloc
Oct 26, 2026
Merged

wan9chi merged 1 commit into
mainfrom
fix/fspy-execl-bump-alloc

Conversation

@wan9chi

@wan9chi wan9chi commented Oct 26, 2026

Copy link
Copy Markdown
Member

Motivation

execl, execlp and execle pass their arguments as a variadic list, so the interposer has to build an argv array before it can handle the exec. It used a 32-slot stack array, fell back to libc malloc for longer lists, and failed with E2BIG past a hardcoded 4096 arguments. That split is where #865's out-of-bounds write lived, and the malloc fallback isn't async-signal-safe: exec may run in the child of fork(), where malloc's lock may be held by a thread that no longer exists.

Change

  • A small collect_argv pushes arg and the variadic arguments, up to and including the NULL, into an allocator_api2::vec::Vec in the call's pooled_bump(), and leaves the VaList where execle reads envp.
  • Each of the three interposers creates one bump and passes it to both collect_argv and handle_exec, as execveat already does.
  • with_argv.rs is removed along with the stack/heap split and the 4096-argument limit; the real execve reports E2BIG instead.

The rest of the exec path still allocates through libc malloc (RawExec::to_exec/from_exec, fexecve); the PR stacked on this one removes that.

🤖 Generated with Claude Code

`execl`, `execlp` and `execle` built their argv array in a 32-slot stack
array, fell back to libc malloc for longer lists, and failed with E2BIG
past a hardcoded 4096 arguments. malloc is not async-signal-safe: exec
may run in the child of fork(), where malloc's lock may be held by a
thread that no longer exists.

Push the arguments into a Vec in the call's pooled bump instead, and
pass that bump on to handle_exec, as execveat already does. This drops
the stack/heap split, the hardcoded limit, and the closure-based
with_argv helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

fspy benchmark

linux

dynamic/launch             change  +0.57%  [ -3.04% ..  +4.58%]  overhead   +52.55%
dynamic/access             change  +0.04%  [ -3.25% ..  +4.12%]  overhead   +21.84%
dynamic/access-relative    change  +1.81%  [ -1.14% ..  +5.61%]  overhead   +73.48%
dynamic/access-contended   change  -1.89%  [-10.18% ..  +2.56%]  overhead   +23.00%
static/launch              change  +0.32%  [ -3.28% ..  +3.71%]  overhead  +186.67%
static/access              change  +0.07%  [ -2.04% ..  +2.06%]  overhead +1366.06%
static/access-relative     change  -0.07%  [ -1.15% ..  +1.01%]  overhead +1863.99%
static/access-contended    change  +0.52%  [ -0.78% ..  +0.94%]  overhead +1942.85%

macos

dynamic/launch             change  -0.13%  [ -4.87% ..  +5.02%]  overhead  +232.68%
dynamic/access             change  +0.34%  [-10.28% .. +26.92%]  overhead    +2.94%
dynamic/access-relative    change  +0.28%  [ -8.55% .. +25.35%]  overhead  +246.84%
dynamic/access-contended   change  +2.01%  [ -9.98% .. +698.93%]  overhead    -2.08%

windows

dynamic/launch             change  -0.15%  [ -1.50% ..  +1.74%]  overhead   +25.75%
dynamic/access             change  -0.19%  [ -0.75% ..  +0.77%]  overhead    +0.99%
dynamic/access-relative    change  +0.18%  [ -1.08% ..  +1.09%]  overhead    +1.28%
dynamic/access-contended   change  +0.00%  [ -1.05% ..  +0.90%]  overhead    +1.26%

@wan9chi
wan9chi added this pull request to stack #895 October 26, 2026 07:26
@wan9chi
wan9chi merged commit 6d1a6b2 into main Oct 26, 2026
21 checks passed
@wan9chi
wan9chi deleted the fix/fspy-execl-bump-alloc branch October 26, 2026 07:37
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