From 9346d8d8f227ea469f2b26fea82c2da29f06b618 Mon Sep 17 00:00:00 2001 From: Alex Langford Date: Wed, 9 Jul 2025 14:53:15 -0700 Subject: [PATCH] [Support] Don't re-raise signals sent from kernel (#145759) When an llvm tool crashes (e.g. from a segmentation fault), SignalHandler will re-raise the signal. The effect is that crash reports now contain SignalHandler in the stack trace. The crash reports are still useful, but the presence of SignalHandler can confuse tooling and automation that deduplicate or analyze crash reports. rdar://150464802 (cherry picked from commit 9337594e3346e15b5bc90b5372b8b482aa5af37f) --- llvm/lib/Support/Unix/Signals.inc | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Support/Unix/Signals.inc b/llvm/lib/Support/Unix/Signals.inc index 1f6531d50fb55..86ac4dd8f601d 100644 --- a/llvm/lib/Support/Unix/Signals.inc +++ b/llvm/lib/Support/Unix/Signals.inc @@ -80,6 +80,10 @@ #endif #endif +#if defined(__linux__) +#include +#endif + using namespace llvm; static void SignalHandler(int Sig, siginfo_t *Info, void *); @@ -411,10 +415,21 @@ static void SignalHandler(int Sig, siginfo_t *Info, void *) { raise(Sig); #endif - // Signal sent from another process, do not assume that continuing the - // execution would re-raise it. - if (Info->si_pid != getpid()) +#if defined(__linux__) + // Re-raising a signal via `raise` loses the original siginfo. Recent + // versions of linux (>= 3.9) support processes sending a signal to itself + // with arbitrary signal information using a syscall. If this syscall is + // unsupported, errno will be set to EPERM and `raise` will be used instead. + int retval = + syscall(SYS_rt_tgsigqueueinfo, getpid(), syscall(SYS_gettid), Sig, Info); + if (retval != 0 && errno == EPERM) raise(Sig); +#else + // Signal sent from another userspace process, do not assume that continuing + // the execution would re-raise it. + if (Info->si_pid != getpid() && Info->si_pid != 0) + raise(Sig); +#endif } static void InfoSignalHandler(int Sig) {