summaryrefslogtreecommitdiff
path: root/internal/generate
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-30 10:44:55 +0300
committerPaul Buetow <paul@buetow.org>2026-05-30 10:44:55 +0300
commit5e334d33b3ddc3e308455262577c461835939bc7 (patch)
tree924eaf62dd5e993c327c06a3b2d6f7686d1d038e /internal/generate
parent1491f883fc6feee512e92bde9af884852502dd0b (diff)
test(clock_nanosleep): lock in exit handler UNCLASSIFIED ret + args[2] request ptr
Audit of clock_nanosleep tracing confirmed the classification is correct: KindSleep + FamilyTime (matching the nanosleep sibling), the enter handler captures the request timespec at ctx->args[2] (not args[0]/clockid), and the exit handler emits a plain ret_event with ret_type UNCLASSIFIED, which is correct since clock_nanosleep returns 0 or a positive errno, never an fd or byte count. Strengthen the existing enter-handler test with the requested_ns -1 sentinel and add TestClockNanosleepExitHandlerIsUnclassifiedRet to pin the exit-side behavior. No classification, docs, or generated-code changes were needed (mage generate produces no diff). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat (limited to 'internal/generate')
-rw-r--r--internal/generate/codegen_test.go20
1 files changed, 20 insertions, 0 deletions
diff --git a/internal/generate/codegen_test.go b/internal/generate/codegen_test.go
index bb06418..9bd391e 100644
--- a/internal/generate/codegen_test.go
+++ b/internal/generate/codegen_test.go
@@ -1378,10 +1378,30 @@ func TestGenerateClockNanosleepHandlerCapturesRequestedTimespec(t *testing.T) {
requireContains(t, output, "struct sleep_event *ev")
requireContains(t, output, "ev->event_type = ENTER_SLEEP_EVENT;")
+ // clock_nanosleep(clockid_t, int flags, const struct timespec *request,
+ // struct timespec *remain): the request pointer is args[2], not args[0]
+ // (which is the clockid). The sentinel -1 marks a missing/unreadable ptr.
+ requireContains(t, output, "ev->requested_ns = -1;")
requireContains(t, output, "if (ctx->args[2] != 0) {")
requireContains(t, output, "ev->requested_ns = ts.tv_sec * 1000000000LL + ts.tv_nsec;")
}
+// TestClockNanosleepExitHandlerIsUnclassifiedRet locks in that the exit side of
+// clock_nanosleep records a plain ret_event with ret_type UNCLASSIFIED. The
+// syscall returns 0 on success or a positive errno (and -1 only when invoked
+// via the libc wrapper on error), never an fd or byte count, so UNCLASSIFIED is
+// the correct return classification — same as its nanosleep sibling.
+func TestClockNanosleepExitHandlerIsUnclassifiedRet(t *testing.T) {
+ output := generateFromPair(t, FormatClockNanosleep, FormatExitClockNanosleep)
+
+ requireContains(t, output, "handle_sys_exit_clock_nanosleep")
+ requireContains(t, output, "ev->event_type = EXIT_RET_EVENT;")
+ requireContains(t, output, "ev->ret = ctx->ret;")
+ requireContains(t, output, "ev->ret_type = UNCLASSIFIED;")
+ // The exit handler must not try to read a timespec or treat ret as an fd.
+ requireNotContains(t, output, "handle_sys_exit_clock_nanosleep(struct syscall_trace_exit *ctx) {\n __u32 pid, tid;\n if (filter(&pid, &tid))\n return 0;\n\n if (!ior_on_syscall_exit(tid, SYS_ENTER_CLOCK_NANOSLEEP, ctx->ret))\n return 0;\n\n struct sleep_event")
+}
+
func TestGenerateKeyctlHandler(t *testing.T) {
output := GenerateTracepointsC(mustParseAll(t, syntheticPair("keyctl")))