Skip to content

Add stack read cache to better handle deep stacks during unwind#5

Merged
GuillaumeLagrange merged 7 commits into
codspeedfrom
cod-2634-fix-samply-python-profiling-on-linux
Jun 11, 2026
Merged

Add stack read cache to better handle deep stacks during unwind#5
GuillaumeLagrange merged 7 commits into
codspeedfrom
cod-2634-fix-samply-python-profiling-on-linux

Conversation

@GuillaumeLagrange

Copy link
Copy Markdown

No description provided.

not-matthias and others added 6 commits June 1, 2026 18:18
samply injects DYLD_INSERT_LIBRARIES + SAMPLY_BOOTSTRAP_SERVER_NAME into the
whole descendant tree. Each descendant that loads samply-mac-preload runs a
dyld initializer that sends its mach task-self port to samply so it can be
profiled.

For an Apple *platform binary* (CS_PLATFORM_BINARY) the task-self port is
immovable. Transferring an immovable port to another process raises a fatal
EXC_GUARD / GUARD_TYPE_MACH_PORT (ILLEGAL_MOVE) and the kernel SIGKILLs the
process — inside the preload's mach_msg, before main().

This is not specific to dsymutil: the entire Xcode toolchain is affected
(clang, ld, nm, strip, lipo, dsymutil, ... all confirmed killed by signal 9;
clang++, swift(c), ar, ranlib, otool, dwarfdump, objdump, llvm-* share the same
CS_PLATFORM_BINARY + non-restricted property). dsymutil was just the binary the
original report hit (Go's linker invokes it). Any compile/link step run under
`samply record` breaks as soon as a build tool invokes a toolchain binary by
absolute path (the norm); going through the restricted /usr/bin shims hides it
because they strip DYLD_*. Symptom: "running dsymutil failed: signal: killed".

Confirmed via the crash report (EXC_GUARD "ILLEGAL_MOVE on mach port 515",
port 515 == mach_task_self()) and by probing csops(2): the only distinguishing
bit between a killed platform binary and a surviving locally-built binary is
CS_PLATFORM_BINARY.

Fix: in the preload, detect platform binaries via csops(getpid(),
CS_OPS_STATUS) and skip the task handoff for them. samply cannot profile a
platform binary through this mechanism anyway (its task port is protected), so
nothing is lost; the process runs normally instead of being killed. Descendant
profiling of all normal binaries is unchanged.

Includes a regression test (samply/tests/dsymutil_sigkill.rs). Preload rebuilt
for x86_64/arm64/arm64e.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Resolve SDKROOT via `xcrun --show-sdk-path` instead of a hardcoded
Xcode.app path, and pin clang as the linker for the arm64e
-Zbuild-std target so the build works outside the default toolchain.
Add a no-alloc stderr logger (heapless fixed buffer, no allocator in
a preload) installed from the constructor only when
SAMPLY_PRELOAD_DEBUG is set. Makes it possible to see whether the
preload loaded and completed the samply handoff in a given process.
SIP strips DYLD_* when execing a protected system binary, killing the
preload for that subtree. Publish the preload path under a second,
non-DYLD-prefixed alias that survives stripping, so a downstream
choke point (e.g. CodSpeed's node.sh shim) can restore
DYLD_INSERT_LIBRARIES and re-arm the preload.
Interpose execve/posix_spawn{,p} to detect when a process is about to
exec a SIP-protected Apple system binary (directly or via a shebang
interpreter). macOS strips DYLD_* on that exec, so the preload — and
samply's visibility — silently dies for the whole subtree. We don't
modify the exec; we only print a warning naming the binary, emitted
as a ::warning:: annotation under GitHub Actions.

Rebuild the bundled preload dylibs with the new code.
Comment thread samply/src/linux_shared/converter.rs Outdated
…ange

This is the strategy that HotSpot uses, and is mostly safe.
If we need this, the call chain would have been truncated in the first
place anyway.
@GuillaumeLagrange GuillaumeLagrange force-pushed the cod-2634-fix-samply-python-profiling-on-linux branch from 643bbbc to 629e568 Compare June 11, 2026 16:14
@GuillaumeLagrange GuillaumeLagrange merged commit 629e568 into codspeed Jun 11, 2026
@GuillaumeLagrange GuillaumeLagrange deleted the cod-2634-fix-samply-python-profiling-on-linux branch June 11, 2026 16:15
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.

2 participants