| Age | Commit message (Collapse) | Author |
|
vmsplice(int fd, const struct iovec*, unsigned long nr_segs, unsigned int
flags) is the iovec<->pipe variant of splice(2) and belongs to the same fd
byte-mover cohort as its direct siblings splice/tee (and sendfile64/
copy_file_range). Its KIND (KindFd@arg0) and RET (TransferClassified, byte
count) already matched splice/tee — only the family was wrong.
Root cause: vmsplice was absent from the syscallFamilies map in
internal/generate/family.go; its name matches no fsNameMarkers and it is not
in fsSyscalls, so ClassifySyscallFamily fell through to FamilyMisc. This is
the same documented Misc-fall-through anti-pattern already fixed for
alarm/adjtimex/fanotify_init/fanotify_mark/file_getattr/file_setattr. The
established mj0 decision placed splice/tee in Network, so the minimal
sibling-consistent fix is vmsplice -> Network.
Added "vmsplice": FamilyNetwork next to splice/tee with an explanatory
comment, then re-ran `mage generate`. The regen is minimal and idempotent:
only the two vmsplice trace IDs flip Misc->Network in generated_types.go and
the vmsplice entry flips Misc->Network in generated_tracepoints.go; no
TraceId renumbering and no other syscalls change. The generated C tracepoints
are unaffected (family is a Go-side tag).
Also moved vmsplice from the Misc list to the Network list in
docs/syscall-tracing-plan.md (hand-maintained, docs-drift-validated), and
corrected the misc_test.go comments which described vmsplice as a Misc
syscall — it is still issued by the misc-basic workload and traced by name,
but its transfer/byte-count coverage lives in retbytes_test.go alongside
splice/tee. No vmsplice family assertion existed in the integration suite, so
no coverage was relocated, only comments corrected.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
Root cause: the generic field matcher classifyByField only maps an arg
literally named "fd" to KindFd. Several syscalls operate on an EXISTING
fd whose tracepoint arg0 is named something else, so they fell through
to KindNull -> null_event, capturing NO descriptor and dropping the fd
they act on:
- timerfd_gettime / timerfd_settime: arg0 is "int ufd" (the timerfd)
- splice: arg0 is "int fd_in" (source fd of an in-kernel transfer)
- tee: arg0 is "int fdin" (source fd of an in-kernel transfer)
Fix: add explicit KindFd overrides for these four sys_enter_* keys to
nameOnlyKindsTable so the enter handler captures arg0, mirroring the
established epoll_wait(epfd) / mq_*(mqdes) / sendfile64(out_fd) /
copy_file_range(fd_in) precedent. splice/tee were surfaced by a systemic
sweep of tracepoint formats for fd-typed arg0 named other than "fd" that
currently classify to null; they are TransferClassified siblings of
sendfile64/copy_file_range and clearly fd-operating. The *at() family
(dfd arg0) is intentionally untouched: it is path-classified, and
timerfd_create remains the KindEventfd fd CREATOR.
Regenerated artifacts (mage generate): the four enter handlers now emit
fd_event capturing ctx->args[0] instead of null_event; exit handlers stay
UNCLASSIFIED. Updated the generated kind maps, the golden result.txt, the
classify_test expectations, and docs/syscall-tracing-plan.md (moved the
four from kind "null" to kind "fd"; families IPC/Network unchanged).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
file_setattr(2) (Linux 6.13+) is the write counterpart of file_getattr:
it sets a file's extended attributes (struct file_attr) given dirfd@arg0
+ pathname@arg1 + attr-buffer + size + at_flags, and returns 0/-1 (not a
byte count). Its name matches none of the fsNameMarkers substrings
("stat"/"xattr"/"chmod"/"chown") and it is absent from the fsSyscalls
set, so it was falling through to FamilyMisc -- the same
alarm/fanotify/file_getattr-style misclassification. Add it to the
explicit family map for sibling consistency with file_getattr.
This also completes the file_getattr regeneration: the prior fix
(96de9ef) was generated with a partial target that updated
generated_tracepoints.go but did not propagate file_getattr into the
traceId2Family map in generated_types.go; a full `mage generate` here
reconciles both file_getattr (1058/1059) and file_setattr (1056/1057)
to FamilyFS. mage build, generate idempotency, and the
internal/generate, /tracepoints, /types unit tests (incl. docs-drift
sync) all pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
file_getattr(2) (Linux 6.13+) retrieves a file's extended attributes
(struct file_attr) given a dirfd + pathname + attr buffer + size +
at_flags. It is a path-based filesystem operation, the counterpart of
statx and the FS_IOC_FSGETXATTR ioctl, so it belongs in FamilyFS.
It was falling through to FamilyMisc because the fsNameMarkers substring
list keys on "stat"/"xattr"/"chmod"/"chown" — "getattr" matches none of
them — and the syscall is absent from the fsSyscalls set, the same
Misc-fall-through defect previously fixed for alarm/fanotify_init/
fanotify_mark. Add an explicit "file_getattr": FamilyFS entry to the
syscallFamilies map, regenerate the Go tracepoint map, and update the
docs/syscall-tracing-plan.md family listing to match.
KIND stays KindPathname (pathname@args[1], data-driven from the live
tracepoint) and the return is 0/-1, hence UNCLASSIFIED (not a byte
count) — both already correct, only the family was wrong.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
fanotify_mark(2) adds, removes, or modifies a mark on an fanotify
notification group. Its arg0 is the fanotify group fd returned by
fanotify_init(2); it carries a dirfd@arg3 and an optional pathname@arg4
and returns 0/-1 (not a byte count). It is the operation counterpart of
fanotify_init and the direct analog of inotify_add_watch (both register a
watch/mark on a filesystem object via the notification-group fd).
inotify_add_watch is FamilyIPC, and fanotify_init was just moved Misc->IPC
to sit with the fd-based event-notification primitives (eventfd, signalfd,
timerfd, userfaultfd, inotify_*). fanotify_mark, however, was still falling
through to FamilyMisc by omission from the explicit family table -- the same
alarm/adjtimex-style misclassification fixed for fanotify_init in 88769d4,
and flagged there as still-outstanding for fanotify_mark. Add it to the IPC
family map for sibling consistency and regenerate.
KIND is unchanged and correct: KindPathname capturing the optional
pathname at args[4]. This matches the *at() cohort convention (fchmodat,
fchownat, unlinkat, mkdirat, newfstatat, utimensat, name_to_handle_at all
carry a dirfd at arg0 yet capture the pathname), since fanotify_mark has a
dirfd@arg3 + pathname@arg4 pair. RET stays UNCLASSIFIED (returns 0/-1).
Docs plan updated to keep the docs-drift tests in sync.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
fanotify_init(2) creates and initializes an fanotify notification group
and returns an event-queue file descriptor. It is the direct analog of
inotify_init1 (both are filesystem-event notification facilities whose
group-creating syscall is a flags-taking fd-creator). inotify_init/
inotify_init1 are FamilyIPC alongside the other fd-based event-notification
primitives (eventfd, signalfd, timerfd, userfaultfd), yet fanotify_init
fell through to FamilyMisc by omission from the explicit family table -- an
alarm/adjtimex-style misclassification inconsistent with its siblings.
Add fanotify_init to the IPC family map and regenerate. Kind
(KindEventfd, flags at args[0]) and ret (UNCLASSIFIED, returned fd captured
via the fd mechanism) were already correct and are unchanged. fanotify_mark
stays in Misc (path-marking, not fd creation). Docs plan updated to keep
the docs-drift test in sync.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
alarm(2) arranges for a SIGALRM after a given number of seconds; it is a
simplified setitimer(ITIMER_REAL) and, per alarm(2) NOTES, "alarm() and
setitimer(2) share the same timer; calls to one will interfere with use of
the other." The syscallFamilies table omitted alarm, so it fell through to
FamilyMisc while its siblings setitimer/getitimer/timer_create were correctly
FamilyTime — an adjtimex-style misclassification (cf. 7243b7c). Add
alarm -> FamilyTime and move it from Misc to Time in the tracing plan;
regenerate the family maps (trace IDs 468/469 now FamilyTime,
"alarm": "Time").
Kind classification (KindNull/null_event: the single arg is an unsigned int
seconds, no fd/path) and the UNCLASSIFIED return (seconds remaining, not a
byte count; alarm never fails) were already correct.
Also harden the misc-basic integration test with a deterministic
enter_alarm assertion (alarm(0) is issued unconditionally by the scenario;
the syscall-entry tracepoint always fires) so the alarm enter path is
covered end-to-end even though alarm is now FamilyTime rather than Misc.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
adjtimex(2) and clock_adjtime(2) share one man page: both tune or query
the kernel clock (clock_adjtime is adjtimex with an explicit clockid) and
return a clock-state code or -1. The syscallFamilies table omitted
adjtimex, so it fell through to FamilyMisc while its sibling clock_adjtime
was correctly FamilyTime. Add adjtimex -> FamilyTime and move it from
Misc to Time in the tracing plan; regenerate the family maps (trace IDs
418/419 now FamilyTime, "adjtimex": "Time").
Kind classification (KindNull/null_event) and the UNCLASSIFIED return
(a clock-state code, not a byte count) were already correct.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
rt_sigreturn(2) restores the pre-signal execution context off the signal
stack frame and resumes the interrupted instruction; it never returns to
the instruction after the syscall. man sigreturn(2) states plainly that
"sigreturn() never returns", and tracing against /sys/kernel/tracing
confirms it: sys_enter_rt_sigreturn fires once per signal-handler return
while sys_exit_rt_sigreturn never fires.
The generator previously emitted a dead handle_sys_exit_rt_sigreturn (it
can never run) and recorded a per-tid syscall_enter_state_map entry on the
enter path that nothing would ever delete (no exit fires), leaking entries
in the bounded map on every signal-handler return.
Add rt_sigreturn to noreturnSyscalls so codegen suppresses the dead exit
handler and routes the enter handler through ior_on_noreturn_syscall_enter
(sampling decision only, no map write), exactly like exit/exit_group. The
enter null_event is still emitted, and the FamilySignals/KindNull
classification is unchanged. Regenerated the C/Go artifacts and the result
baseline accordingly, and generalized the related comments.
Lock-in tests: TestRtSigreturnIsNoreturn asserts rt_sigreturn is noreturn;
TestRtSigSiblingsAreNotNoreturn guards that the returning rt_sig* siblings
are not; TestGenerateExitNoreturnHandlers now also covers rt_sigreturn.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
kexec_load(2) and kexec_file_load are documented together on the same
man page and both load a new kernel for later execution by reboot(2).
kexec_file_load was already FamilySecurity, but kexec_load fell through
to FamilyMisc. Move kexec_load to FamilySecurity so the siblings share
a family. Kind classification was already correct: kexec_load takes raw
user pointers (KindNull, no fd/path) while kexec_file_load takes fds
(KindFd); the return value (long 0/-1, no byte count) stays UNCLASSIFIED.
Update docs/syscall-tracing-plan.md to match, regenerate artifacts, and
add lock-in tests for the family and UNCLASSIFIED return of both kexec
syscalls plus reboot.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
sendfile64(out_fd, in_fd, offset, count) transfers bytes between two file
descriptors in the kernel and returns the number of bytes written to out_fd.
Its tracepoint fields carry no field literally named "fd", so it fell through
to KindNull and captured no descriptor at all - inconsistent with its sibling
copy_file_range (KindFd) and the read/write/sendto/recvfrom families.
Add an explicit sys_enter_sendfile64 -> KindFd override that captures out_fd
(args[0], the destination the bytes are written to), matching the single-fd
KindFd convention. The return value stays TransferClassified, consistent with
copy_file_range/splice/tee/vmsplice. Family stays Network (sendfile is
historically socket-oriented; copy_file_range=FS is pure file-to-file).
Update docs/syscall-tracing-plan.md (move sendfile64 from null to fd kind),
regenerate C/Go artifacts, fix the phase-A classify assertion, and add
TestClassifySendfile64CapturesOutFd as a lock-in + negative test. The existing
TestRetbytesPhaseA integration test still passes with the runtime change.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
get_mempolicy(2) retrieves the NUMA memory policy for a thread or
address range and is logically a Memory-family syscall, sharing
FamilyMemory with its NUMA siblings set_mempolicy, set_mempolicy_home_node,
mbind, migrate_pages, and move_pages. It was misclassified FamilySecurity
(a copy/paste/alphabetical-ordering slip alongside the security modules).
Move it to the Memory group in internal/generate/family.go, update the
Memory and Security lists in docs/syscall-tracing-plan.md (keeps the
docs_drift_test green), and regenerate artifacts (traceId2Family 735/734
and syscallFamilies[get_mempolicy] flip Security->Memory; C unchanged,
mage generate idempotent). Add enter+exit family lock-in assertions for
get_mempolicy and set_mempolicy alongside the NUMA siblings so the whole
cluster is pinned.
Task 120.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
Audit of ioprio_set found a family inconsistency. ioprio_set(which, who,
ioprio) and ioprio_get(which, who) query/set the I/O scheduling class and
priority of a process, process group, or user. They are the direct
I/O-priority analogues of getpriority/setpriority (the CPU nice value) and
share the identical which/who selector signature, yet were falling through to
FamilyMisc while getpriority/setpriority are FamilyProcess.
Reclassify both ioprio syscalls to FamilyProcess for consistency with their
priority siblings, update docs/syscall-tracing-plan.md, and regenerate the
tracepoint/type artifacts (mage generate is idempotent).
Argument capture is unchanged and confirmed correct: the args are all ints
(which/who/ioprio), none named fd/path, so ClassifyFormat returns KindNone and
the generator promotes the enter format to KindNull (null_event). In
particular the 'who' argument (a pid/pgid/uid, never an fd) is not
misclassified as KindFd. The exit is a ret_event (UNCLASSIFIED, int 0/-1).
Add lock-in tests:
- TestClassifyIoprioNullKind asserts KindNone/KindNull using the real kernel
tracepoint fields, proving 'who' is not captured as an fd.
- Family assertions for the ioprio pair alongside getpriority/setpriority so a
stray reclassification of any of them trips the test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
utime(2) and utimes(2) change a file's access/modification times by a real
filesystem path (filename at args[0]). The path was already captured
(KindPathname), but both syscalls fell through to FamilyMisc instead of
joining their siblings utimensat/futimesat in FamilyFS. Add them to
fsSyscalls and regenerate; the only generated change is trace IDs
1034-1037 flipping FamilyMisc -> FamilyFS.
Lock-in coverage:
- family_test.go asserts utime/utimes/utimensat/futimesat are all FamilyFS.
- classify_test.go + FormatUtime fixture assert utime is KindPathname with
PathnameField "filename" (path captured even though it is a char* string,
unlike domain/host name args).
- New ioworkload scenarios utime-basic/utimes/enoent and integration tests
TestUtimeBasic/Utimes/Enoent verify the path is captured at runtime,
including on the ENOENT error path.
Docs updated: moved utime/utimes from Misc to FS in
docs/syscall-tracing-plan.md to keep the drift tests green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
The Linux Security Module introspection syscalls lsm_list_modules,
lsm_get_self_attr and lsm_set_self_attr (Linux 6.8+) were classified as
FamilyMisc while every sibling LSM/security syscall (landlock_*, keyctl,
add_key, request_key, seccomp) is FamilySecurity. This audited
inconsistency is fixed by adding the three lsm_* entries to the
syscallFamilies map; their kind stays KindNull (args are userspace
pointers + flags, no fd/path) and the exit remains a ret_event.
Docs (syscall-tracing-plan.md) updated accordingly, generated artifacts
regenerated via mage generate, and lock-in family assertions added to
TestClassifySyscallPairEmitsAllFamilies.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
exit and exit_group never return to userspace, so their sys_exit
tracepoints can never fire. The generator previously emitted matching
EXIT_RET_EVENT handlers anyway, producing dead code in the generated BPF
program. classifySyscall now skips exit-handler emission for noreturn
syscalls via isNoreturnSyscall, and the regenerated artifacts drop the
sys_exit_exit / sys_exit_exit_group handlers (enter handlers are kept).
Tests updated to match the new reality:
- TestGenerateExitNoreturnHandlers asserts no exit handler is emitted.
- TestClassifySyscallPairEmitsAllFamilies exempts noreturn syscalls from
the exit-handler-required assertion while staying strict for all others.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
Audit of futex_wake found that the futex family syscalls (futex,
futex_wait, futex_wake, futex_requeue, futex_waitv) were absent from the
syscallFamilies map and fell through to FamilyMisc. Per futex(2) ("fast
user-space locking"), these are shared-memory synchronization/IPC
primitives, conceptually identical to the System V semaphores
(semop/semget) already tagged FamilyIPC. Group them under IPC so
per-family aggregation/reporting bins them with the other synchronization
primitives.
Argument and return-value handling were already correct: futex_wake's
first arg (uaddr) is a userspace pointer, captured via KindFutex
(null_event), and the exit ret_event records the woken-waiter count
(>=0) or -1 on error.
Add lock-in unit tests in family_test.go and regenerate the C/Go
artifacts (generated_tracepoints.go, generated_types.go).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
close_range was captured as a single-fd fd_event carrying only first, so
the runtime evicted every tracked fd >= first, ignoring the last upper
bound and the flags. Bounded calls wrongly dropped still-open higher fds,
and CLOSE_RANGE_CLOEXEC (which keeps fds open) was treated as a full close.
Reclassify close_range to the two_fd_event kind, mapping fd_a/fd_b/extra to
first/last/flags. The runtime now closes only the inclusive [first, last]
range (a negative last from ~0U means unbounded) and skips eviction when
CLOSE_RANGE_CLOEXEC is set or the syscall fails.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
|
When -tps provides an explicit regex but no -trace-* dimension selectors
are given, skip the implicit FS-only syscall allowlist so that non-FS
tracepoints (e.g. nanosleep) matched by the regex are still attached.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- Add tracepoints.Selector type with ShouldAttach method and ParseSelector
constructor, replacing the raw TracepointsToAttach/TracepointsToExclude
regex slices on flags.Config.
- Add flags.BuildTraceFilter as a standalone function replacing the
Config.TraceFilter() method, keeping filter-building logic out of the
config struct.
- Remove stale ShouldIAttachTracepoint noise-filter entry from Magefile.
- Add selector_test.go with full coverage of ParseSelector and ShouldAttach.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|
|
|
|
|
|
|
|
|
|
Amp-Thread-ID: https://ampcode.com/threads/T-019c7fec-eec9-706a-8338-3ce674802680
Co-authored-by: Amp <amp@ampcode.com>
|
|
Amp-Thread-ID: https://ampcode.com/threads/T-019c7f4e-cc5f-76f1-aaf0-dd7cbaabbb18
Co-authored-by: Amp <amp@ampcode.com>
|
|
|
|
|
|
|
|
|
|
|