From 136c4dfb6846595b98cf2b04a93525ce91d86d5e Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sat, 30 May 2026 22:25:49 +0300 Subject: generate: treat rt_sigreturn as noreturn (suppress dead exit handler) 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 --- internal/generate/bpfhandler.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'internal/generate/bpfhandler.go') diff --git a/internal/generate/bpfhandler.go b/internal/generate/bpfhandler.go index 1dff4d6..071e11d 100644 --- a/internal/generate/bpfhandler.go +++ b/internal/generate/bpfhandler.go @@ -36,10 +36,11 @@ func generateBPFHandler(tp GeneratedTracepoint) string { // between kernel-assigned enter/exit IDs. enterName := enterConstForHandler(f.Name, isEnter) - // Noreturn syscalls (exit, exit_group) get a special enter hook that skips - // the syscall_enter_state_map write. Their exit handler is suppressed (see - // codegen.go), so nothing would ever clear a recorded enter-state entry; - // recording it would only leak stale per-tid entries in the bounded map. + // Noreturn syscalls (exit, exit_group, rt_sigreturn) get a special enter + // hook that skips the syscall_enter_state_map write. Their exit handler is + // suppressed (see codegen.go), so nothing would ever clear a recorded + // enter-state entry; recording it would only leak stale per-tid entries in + // the bounded map. noreturn := isEnter && isNoreturnSyscall(syscallName(f.Name)) return renderHandler(f.Name, ctxStruct, eventStruct, comment, eventTypeConst, extra, isEnter, noreturn, enterName) -- cgit v1.2.3