summaryrefslogtreecommitdiff
path: root/internal/generate/bpfhandler.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-30 22:25:49 +0300
committerPaul Buetow <paul@buetow.org>2026-05-30 22:25:49 +0300
commit136c4dfb6846595b98cf2b04a93525ce91d86d5e (patch)
tree32c4eb7a6203879796c4598d82f51c028a182971 /internal/generate/bpfhandler.go
parentdb7c18b976c6bb87ca3dbbfdf436c1945aab3289 (diff)
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 <noreply@anthropic.com>
Diffstat (limited to 'internal/generate/bpfhandler.go')
-rw-r--r--internal/generate/bpfhandler.go9
1 files changed, 5 insertions, 4 deletions
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)