diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-30 22:25:49 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-30 22:25:49 +0300 |
| commit | 136c4dfb6846595b98cf2b04a93525ce91d86d5e (patch) | |
| tree | 32c4eb7a6203879796c4598d82f51c028a182971 /internal/generate/bpfhandler.go | |
| parent | db7c18b976c6bb87ca3dbbfdf436c1945aab3289 (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.go | 9 |
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) |
