Skip to content

fix(ptrace): handle duplicated syscall exit stops with restarted sysc…#296

Merged
kxxt merged 1 commit into
mainfrom
restarted-syscall-exit
Jul 18, 2026
Merged

fix(ptrace): handle duplicated syscall exit stops with restarted sysc…#296
kxxt merged 1 commit into
mainfrom
restarted-syscall-exit

Conversation

@kxxt

@kxxt kxxt commented Jul 18, 2026

Copy link
Copy Markdown
Owner

…alls

Summary by CodeRabbit

  • Bug Fixes

    • Improved ptrace syscall tracking to reliably distinguish syscall entry and exit events.
    • Fixed tracing behavior for restarted syscalls that produce consecutive exit events.
    • Improved handling when attaching to an already-running process, including its first exit stop.
    • Gracefully handles processes that exit while syscall information is being collected.
  • Tests

    • Added regression coverage for attaching to processes during sleep and verifying successful completion.

@vercel

vercel Bot commented Jul 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
tracexec Ready Ready Preview, Comment Jul 18, 2026 2:19pm

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The tracer now reads fresh syscall metadata to distinguish entry and exit stops, including seccomp stops, and adds test-only support for attaching to an existing tracee. A regression test covers ptrace restart behavior during nanosleep.

Changes

Ptrace syscall-stop handling

Layer / File(s) Summary
Kernel-based syscall dispatch
crates/tracexec-backend-ptrace/src/ptrace/syscall.rs, crates/tracexec-backend-ptrace/src/ptrace/tracer/inner.rs
Adds SyscallInfo::is_entry() and routes syscall and seccomp stops using freshly read syscall metadata passed to the entry and exit handlers.
Attached trace execution
crates/tracexec-backend-ptrace/src/ptrace/tracer.rs, crates/tracexec-backend-ptrace/src/ptrace/tracer/inner.rs
Adds test-only attachment helpers that seize an existing tracee, consume its initial stop, initialize process state, and run the wait loop.
Attach restart regression coverage
crates/tracexec-backend-ptrace/src/ptrace/tracer/test.rs
Adds a nanosleep helper and regression test verifying successful tracee exit after attaching and ptrace restart.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Test
  participant Tracer
  participant TracerInner
  participant Tracee
  participant ptrace_kernel
  Test->>Tracee: launch nanosleep helper
  Tracee->>Test: publish tracee TID
  Test->>Tracer: attach_for_test(pid)
  Tracer->>TracerInner: run_attached(pid)
  TracerInner->>ptrace_kernel: seize tracee
  ptrace_kernel-->>TracerInner: initial syscall stop
  TracerInner->>ptrace_kernel: read syscall_info
  ptrace_kernel-->>TracerInner: entry or exit metadata
  TracerInner->>Tracee: process syscall stop
  Tracee-->>Test: successful exit event
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main ptrace fix for duplicated syscall exit stops caused by restarted syscalls.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch restarted-syscall-exit

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request improves the reliability of the ptrace tracer when handling restarted syscalls. Instead of relying on a local boolean state (presyscall) to track whether a syscall stop is an entry or exit, the tracer now queries the kernel-reported stop kind authoritatively using SyscallInfo::is_entry(). Additionally, a regression test has been added to verify that the tracer correctly handles duplicated syscall exit stops after attaching to a blocked process. I have no feedback to provide as there are no review comments.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/tracexec-backend-ptrace/src/ptrace/tracer/test.rs`:
- Around line 607-617: Replace the fixed delay in the ready_thread closure with
synchronization that waits until tracee_tid is confirmed blocked in nanosleep,
then write its TID to ready_path. Ensure the readiness signal is emitted only
after the target syscall is active, while preserving the existing nanosleep
assertion and ptrace-restart test flow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: e57bb21f-94ee-4922-81dd-250f5f4d90ae

📥 Commits

Reviewing files that changed from the base of the PR and between 2c2c05a and 8627c1a.

📒 Files selected for processing (4)
  • crates/tracexec-backend-ptrace/src/ptrace/syscall.rs
  • crates/tracexec-backend-ptrace/src/ptrace/tracer.rs
  • crates/tracexec-backend-ptrace/src/ptrace/tracer/inner.rs
  • crates/tracexec-backend-ptrace/src/ptrace/tracer/test.rs

Comment on lines +607 to +617
let ready_thread = std::thread::spawn(move || {
std::thread::sleep(Duration::from_millis(20));
std::fs::write(ready_path, tracee_tid.as_raw().to_string()).unwrap();
});

let request = nix::libc::timespec {
tv_sec: 0,
tv_nsec: 500_000_000,
};
let result = unsafe { nix::libc::nanosleep(&request, std::ptr::null_mut()) };
assert_eq!(result, 0, "nanosleep should complete after ptrace restart");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Make readiness prove that nanosleep is active.

The fixed 20 ms delay does not establish this contract. Under scheduling delays, the 500 ms sleep can finish before the TID is published, allowing the regression to pass without exercising restart handling—or fail intermittently. Publish readiness only after confirming the target thread is blocked in the intended syscall.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/tracexec-backend-ptrace/src/ptrace/tracer/test.rs` around lines 607 -
617, Replace the fixed delay in the ready_thread closure with synchronization
that waits until tracee_tid is confirmed blocked in nanosleep, then write its
TID to ready_path. Ensure the readiness signal is emitted only after the target
syscall is active, while preserving the existing nanosleep assertion and
ptrace-restart test flow.

@codecov

codecov Bot commented Jul 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.54167% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.25%. Comparing base (9648dc5) to head (8627c1a).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...tracexec-backend-ptrace/src/ptrace/tracer/inner.rs 83.33% 9 Missing ⚠️
...rates/tracexec-backend-ptrace/src/ptrace/tracer.rs 90.90% 1 Missing ⚠️
.../tracexec-backend-ptrace/src/ptrace/tracer/test.rs 96.29% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #296      +/-   ##
==========================================
+ Coverage   82.22%   82.25%   +0.03%     
==========================================
  Files          84       84              
  Lines       20960    21026      +66     
==========================================
+ Hits        17234    17295      +61     
- Misses       3726     3731       +5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@kxxt
kxxt merged commit 939083b into main Jul 18, 2026
25 checks passed
@kxxt
kxxt deleted the restarted-syscall-exit branch July 18, 2026 14:26
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