fix(fspy): record file accesses made inside signal handlers - #687
Merged
Conversation
The HANDLING_OPEN thread-local guard (#540) suppressed same-thread re-entry into handle_open because resolving and reporting an access then called interposable libc symbols, and on Linux an LD_PRELOAD library's own PLT calls resolve to its own exported interposers, recursing until the traced process overflowed its stack. That vector is gone on both platforms: on Linux the handler's whole call graph is raw syscalls (rustix/linux_raw resolution, itoa fd formatting, mmap-backed pooled bump, shm atomics), so nothing binds through the PLT; on macOS the handler still calls libSystem, but dyld never applies __interpose tuples to the image that provides them — the exemption every original() forward already relies on. Dropping the guard fixes a real gap — it silently discarded accesses made by signal handlers that interrupt an in-flight interception, exactly the case the signal-safe allocator work supports — and removes a std TLS dependency from the hot path. A comment on handle_open records the invariant: the handler must stay free of bindable libc calls on Linux, and the macOS argument holds only under __interpose-style interposition. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fspy benchmarklinuxmacoswindows |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
The
HANDLING_OPENthread-local guard (#540) suppressed same-thread re-entry intohandle_openbecause, at the time, resolving and reporting an access called interposable libc symbols —getcwd,readlink,fcntlthrough nix, plusCString::new(format!(...))— and on Linux an LD_PRELOAD library's own PLT calls resolve to its own exported interposers, recursing until the traced process overflowed its stack.That vector no longer exists, on either platform for its own reason:
fspy_nostd's rustix/linux_rawwrappers, fd formatting throughitoa, allocation through the mmap-backed pooled bump, reporting through atomics on the shared mapping. Nothing binds through the PLT.__interposesection, and dyld never applies interposing tuples to the image that provides them — the same exemption everyoriginal()forward has always relied on.Dropping the guard also fixes a real gap: it silently discarded legitimate accesses made by signal handlers that interrupt an in-flight interception — exactly the case the signal-safe allocator work exists to support — and it removes a std TLS dependency from the hot path, which the std-free preload roadmap has to shed anyway.
A comment on
handle_opennow records the invariant this rests on: the handler must stay free of bindable libc calls on Linux, and the macOS argument holds only under__interpose-style interposition.🤖 Generated with Claude Code