feat: aarch64 tracer port + Linux aarch64 wheel publishing#81
Open
christophergeyer wants to merge 9 commits intomainfrom
Open
feat: aarch64 tracer port + Linux aarch64 wheel publishing#81christophergeyer wants to merge 9 commits intomainfrom
christophergeyer wants to merge 9 commits intomainfrom
Conversation
Move syscall numbers, audit-arch, and register access into a new target-gated `arch` module so the ptrace tracer compiles and runs on both x86_64 and aarch64. The previous code hardcoded x86_64 register fields (orig_rax, rax, rdi, rsi, rdx, r10, r8) and AUDIT_ARCH_X86_64; on aarch64 those don't exist on libc::user_regs_struct and the audit arch must be AUDIT_ARCH_AARCH64. Syscalls that don't exist on aarch64 (open/rename/link) are mapped to distinct out-of-range sentinels so shared match arms keyed on them stay compilable but never fire. Preflight now accepts both x86_64 and aarch64 hosts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Several syscall tracepoints don't exist on aarch64 because the syscalls
themselves don't exist there: sys_enter_open / sys_enter_rename /
sys_enter_link / sys_enter_dup2 / sys_enter_fork / sys_enter_vfork.
The previous attach loop hard-failed on the first missing tracepoint
with "No such file or directory", so the whole tracer aborted on
aarch64.
Probe `/sys/kernel/{tracing,debug/tracing}/events/<cat>/<tp>/id` before
attaching; if the tracepoint isn't there, log a warning and continue.
This also makes the tracer robust to kernels built without
CONFIG_FTRACE_SYSCALLS for a particular syscall.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
scripts/test_tracers_sandbox.py runs a single-process Python workload (read input.txt -> write output.txt) under each tracer backend and checks the resulting msgpack report contains both files. Useful for local validation after a build, especially when porting the tracers to a new arch. Uses a Python workload rather than the more obvious `bash -c "echo > x"` because there's a known race where short-lived shell-spawned writes can complete before the tracer observes them; an in-process read+write avoids that flake. Backends that aren't available (binary not built, eBPF without CAP_BPF, etc.) are reported as SKIP rather than FAIL so the script is meaningful to run unprivileged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
scripts/build_wheel_with_bins.sh and scripts/sync_packaged_rust_artifacts.py both hardcoded x86_64-unknown-linux-gnu.2.17 as the cargo-zigbuild target. On aarch64 hosts that produced wrong-arch (x86_64) ELFs in roar/bin and a silently-broken wheel. Detect host arch (uname -m / platform.machine()) and pick the matching target triple (x86_64 or aarch64), keeping the manylinux2014 glibc 2.17 floor. The reusable Build Rust Binaries GitHub action grows a `target` input so callers can pass either x86_64 or aarch64 explicitly. Also runs ruff format on the touched scripts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The maturin include directive shipped pre-built tracer binaries inside the sdist, so sdist installs on a non-x86_64 host got x86_64 ELFs that failed at exec time with "Exec format error" — silent on the install side, broken on first roar run. Drop the sdist entry; the wheel still includes roar/bin/* via the wheel-only entry. sdist users build the binaries from the rust/ source tree. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
build-rust-binaries-linux is now a matrix over (ubuntu-latest, x86_64) + (ubuntu-24.04-arm, aarch64). The wheel matrix gains 4 aarch64 entries (cp310..cp313 on ubuntu-24.04-arm). The publish job's expected wheel count rises from 12 to 16 and now asserts both Linux x86_64 and aarch64 wheels are present. build-sdist no longer copies binaries into roar/bin since the sdist include excludes them — see the prior commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…table
The aarch64 install regression was a sdist that shipped x86_64 ELFs
with no exec bit. The wheel-side equivalent would be just as silently
broken: a Linux wheel with the wrong arch in roar/bin would install
fine but fail at exec. Add two assertions to verify_wheel_contents.py:
- read e_machine from each bundled ELF and require it to match the
wheel's platform tag (x86_64 wheels → 0x3E, aarch64 wheels → 0xB7)
- require the executable bit on bundled binaries (libroar*.so are
exempted)
Both assertions fire as part of the existing "Verify wheel contents"
step in CI, so a wrong-arch or non-exec payload fails the publish
pipeline instead of shipping.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous commit dropped pre-built binaries from the sdist, but cargo's auto-included package list (anchored at artifact-hash-py) doesn't reach the tracer/proxy crates, so sdist users had no way to build the binaries either. Add explicit maturin sdist includes for rust/tracers/**, rust/services/**, rust/crates/tracer-*/**, and the artifact sync script. Also documents the sdist install path in the README: when a matching wheel isn't available, the install requires a C toolchain and Rust to compile tracers — replacing what was previously a silent broken install. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 9, 2026
The CI workflow's `pull_request: branches: [main]` filter meant only PRs whose base is `main` triggered CI. Stacked PRs (cg/foo → cg/bar) landed blind: PRs #83–#87 in the current ptrace/eBPF/preload stack all reported "no checks reported on the branch" because each one targets a feature-branch base. Drop the branch filter on `pull_request` so CI fires for every PR regardless of base. The `push: branches: [main]` constraint stays — we don't want to burn CI minutes on every feature-branch push, only on PR diffs and main. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
archmodule isolates syscall numbers, audit-arch, and register access soroar-tracercompiles and runs on both x86_64 and aarch64 (previously hardcodedorig_rax/rdi/rsi/etc. that don't exist onlibc::user_regs_structfor arm64)./sys/kernel/{tracing,debug/tracing}/events/<cat>/<tp>/idbefore attaching so missing tracepoints (e.g.sys_enter_open/rename/link/dup2/fork/vforkon aarch64) are skipped with a warning instead of aborting the whole tracer.scripts/build_wheel_with_bins.shandscripts/sync_packaged_rust_artifacts.pydetect host arch (uname/platform.machine()) and pick the matching cargo-zigbuild target. The reusable Build Rust Binaries action grows atargetinput.publish-pypi.ymlandpublish-testpypi.ymlmatrixbuild-rust-binaries-linuxover(ubuntu-latest, x86_64)+(ubuntu-24.04-arm, aarch64)and add 4 aarch64 wheel matrix entries (cp310–cp313). Expected wheel count 12 → 16.roar/bin/*in the sdist (which was bundling x86_64 ELFs into a source dist that aarch64 hosts then fell through to). Instead the sdist now ships the tracer Rust source so an sdist install with cc + cargo can build the binaries; README documents the requirement.scripts/ci/verify_wheel_contents.pynow reads e_machine from each bundled ELF and requires it to match the wheel's platform tag, plus asserts the executable bit on bundled binaries. A wrong-arch or non-exec payload now fails CI.scripts/test_tracers_sandbox.pyfor local validation: runs a single-process Python read+write under each backend (avoids the known shell-spawned-write race) and asserts the msgpack report saw both files.Test plan
Verified end-to-end on both arches.
aarch64 (AWS Graviton, Ubuntu 26.04, kernel 7.0.0-1004-aws)
x86_64 (parallel verification)
Same 10 steps, all clean — wheel emits `linux_x86_64` with x86_64 ELFs in bin/, identical pytest counts.
Lint / format
🤖 Generated with Claude Code