feat(crashtracker): add opt-in signal-safe collector#2198
Draft
pawelchcki wants to merge 34 commits into
Draft
Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ignal_safe_crashtracker
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Supersede signal_safe_collector_improvement_plan.md with a consolidated signal_safe_crashtracker_plan.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Trim the collector_signal_safe public surface, remove dead emitter/config paths, reuse rustix/system helpers, and move signal/si-code names into shared Rust code.
Contributor
Clippy Allow Annotation ReportComparing clippy allow annotations between branches:
Summary by Rule
Annotation Counts by File
Annotation Stats by Crate
About This ReportThis report tracks Clippy allow annotations for specific rules, showing how they've changed in this PR. Decreasing the number of these annotations generally improves code quality. |
Contributor
📚 Documentation Check Results📦
|
Contributor
🔒 Cargo Deny Results📦
|
|
Use thiserror's no-std-capable derive for signal-safe initialization errors while keeping the std feature explicit for normal crashtracker builds.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
# Conflicts: # libdd-crashtracker/src/lib.rs
- Drop protocol_marker! macro in favor of a module-level allow(dead_code) - Collapse duplicate errno_location cfg branches - Remove cstr_starts_with pass-through wrapper - Factor Capabilities/Degradations into a shared bitset_u32! macro - Remove scratch planning doc
Single-source the receiver-path capacity as PATH_CAPACITY, replace the hand-rolled eq_ic with eq_ignore_ascii_case, flatten the collect_crash fork flow, dedup the sanitize_clone stdio fallback, drop a redundant getpid syscall on the crash path, and inline put_marker_line.
Remove all environment reading from the signal-safe collector: the consumer populates SignalSafeInitConfig directly. Drops the from-env init path (init_from_env, prepare_from_env_result, disabled_by_env, env_get and helpers) and neutralizes the identity defaults (no hardcoded dd-trace-c name or /opt install path, no option_env! build hooks); COMPAT_* renamed DEFAULT_* with neutral placeholders. Remove the signal-safe FFI bridges (crashtracker-ffi module + feature, profiling-ffi feature, cbindgen exclude, C example, builder wiring, CI step); the Rust collector module stays. Also dedup gettid on the crash path, let capabilities::publish be the sole report_fd validator, and revert the unrelated libdd-profiling-ffi EncodedProfile rework.
Collapse emit_report_sections guards into a short-circuit chain, dedup the init_with_prepare cleanup paths, and use is_some_and in state.rs. On the crash path, snapshot the capability word once instead of re-loading it, and resolve effective_target a single time in the signal handler.
…range Bump rustix to =1.1.4 and enable its runtime feature. Replace the hand-rolled clone/exit_group inline asm with rustix::runtime::kernel_fork and exit_group, which issue the same bare syscalls through the linux_raw backend without running libc atfork handlers. Drop SYS_close_range (Linux 5.9+, unavailable on kernels as old as CentOS 7's 3.10) in favor of a close() loop bounded by the RLIMIT_NOFILE soft limit, so descriptor hygiene before exec works on old kernels instead of silently no-opping. dup3 and process_vm_readv stay as raw syscalls (rustix's dup3 requires owned fds; process_vm_readv is absent).
Disable the inherited alternate signal stack (SS_DISABLE) in forked children so a re-armed handler can never run on a stack region the child no longer maintains, and ignore SIGPIPE in the collector child so a dead receiver surfaces as EPIPE (handled by the sink) instead of terminating the collector mid-report. Also read bytes via a pointer cast in cstr_has_prefix so the comparison does not depend on c_char's platform-varying signedness, fixing an unnecessary-cast clippy error on aarch64-linux.
Stage report output in FdSink and flush in a few write(2) syscalls instead of the ~40 tiny ones report emission previously issued (every marker, body, and trailing newline was its own write). Buffering lives inside the sink, so the protocol framing, emitter, and wire bytes are unchanged; callers flush before closing the fd, and Drop flushes as a safety net. Also fold in signal-safe collector cleanups: - drop the dead INSTALLED atomic (tracked HANDLERS_ENABLED exactly, read only in one test) - collapse the three copy-paste capability guards into a table loop - default runtime_id to the zero UUID in prepare_result instead of hardcoding it on the crash path
Fix tolerant raw fd closing, receiver abnormal-exit fallback, and Linux clippy regressions. Trim unreachable app-handler chaining code and pin the signal-safe workflow action to the allowlisted SHA.
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
Refactors the signal-safe crashtracker collector cleanup plan into code.
collector_signal_safepublic surface and removes dead emitter/config paths.rustixwhile keeping raw syscalls only where needed.Validation
Passed locally:
cargo check -p libdd-crashtracker --no-default-features --features collector_signal-safecargo check -p libdd-crashtrackerx86_64-unknown-linux-gnu,aarch64-unknown-linux-gnu, andaarch64-apple-darwincargo +nightly-2026-02-08 fmt --all -- --checkcargo +stable clippy --workspace --all-targets --all-features -- -D warningscargo nextest run -p libdd-crashtracker --features collector_signal-safe,generate-unit-test-files --no-fail-fastcargo test --doc -p libdd-crashtracker./tools/check_signal_safe_symbols.sh./scripts/update_license_3rdparty.shgit diff --checkKnown local validation caveats:
cargo deny checkruns but fails on existing workspace-wide deny/advisory/license issues.cargo nextest run --workspace --no-fail-fastended with2092 passed, 2 failed, 5 skipped; the FFE fixture test is blocked by an uninitializeddatadog-ffe-test-suite/ffe-system-test-datasubmodule, andtest_crash_tracking_bin_sigchld_sigstackpassed when rerun in isolation.