From 6a75c73eebd4d497ded7d08b47894f9ddbebb5a9 Mon Sep 17 00:00:00 2001 From: Kumar Kartikeya Dwivedi Date: Sat, 26 Sep 2026 17:45:14 +0200 Subject: [PATCH] bpftool: Exit from the stream wait signal handler with _exit() bpftool prog tracelog -w ends from its SIGINT, SIGHUP and SIGTERM handler, which calls exit(). exit() is not async-signal-safe: it runs atexit handlers and flushes stdio streams, and the signal may land while the read loop is inside fwrite() or fflush() on the stream being flushed. Whether that deadlocks or flushes a half-updated buffer depends on the C library. Call _exit() instead. The loop flushes every chunk as soon as it is printed, so the stdio buffer is empty except while a chunk is being written, and skipping the exit-time flush loses nothing. While here, note in the manual page that opening a stream as a file descriptor arrives in Linux 7.4, and restrict the -w/--wait description to the stdout/stderr form of the tracelog command, since the trace pipe form does not take the option. Signed-off-by: Kumar Kartikeya Dwivedi Signed-off-by: Daniel Borkmann Acked-by: Quentin Monnet Link: https://lore.kernel.org/bpf/d64c6402-175f-4ea6-be6d-1a544a95c97c@qmon.net Link: https://lore.kernel.org/bpf/20260926154515.191689-1-memxor@gmail.com --- tools/bpf/bpftool/Documentation/bpftool-prog.rst | 8 +++++--- tools/bpf/bpftool/prog.c | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst index 17aa0d560e32..8dbd34ef3d8b 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst @@ -190,7 +190,8 @@ bpftool prog tracelog { stdout | stderr } *PROG* By default, bpftool prints the output buffered so far and exits. With **-w** or **--wait**, it keeps printing new output as the program produces it, until the program is unloaded or is hit. Waiting requires a - kernel that supports opening a stream as a file descriptor. + kernel that supports opening a stream as a file descriptor, introduced + upstream in Linux 7.4. bpftool prog run *PROG* data_in *FILE* [data_out *FILE* [data_size_out *L*]] [ctx_in *FILE* [ctx_out *FILE* [ctx_size_out *M*]]] [repeat *N*] Run BPF program *PROG* in the kernel testing infrastructure for BPF, @@ -274,8 +275,9 @@ OPTIONS signing. -w, --wait - When dumping a program stream with **bpftool prog tracelog**, wait for new - output instead of exiting once the buffered output has been printed. + When dumping a program stream with **bpftool prog tracelog** { **stdout** | + **stderr** } *PROG*, wait for new output instead of exiting once the + buffered output has been printed. EXAMPLES ======== diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index 5e27b22444f2..a60414aaa494 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -1121,7 +1121,7 @@ enum prog_tracelog_mode { static void exit_stream(int signo) { - exit(0); + _exit(0); } /* Consumes prog_fd. */