diff options
author | Alex Langford <alangford@apple.com> | 2025-07-09 14:53:15 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-09 14:53:15 -0700 |
commit | 9337594e3346e15b5bc90b5372b8b482aa5af37f (patch) | |
tree | 025a73485d3f1b05c11cb800cb2842d0645540a7 /llvm/lib/Support/Unix/Signals.inc | |
parent | 6d00c4297f6714c03ab10f57c10063ebd79264a1 (diff) | |
download | llvm-9337594e3346e15b5bc90b5372b8b482aa5af37f.zip llvm-9337594e3346e15b5bc90b5372b8b482aa5af37f.tar.gz llvm-9337594e3346e15b5bc90b5372b8b482aa5af37f.tar.bz2 |
[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
Diffstat (limited to 'llvm/lib/Support/Unix/Signals.inc')
-rw-r--r-- | llvm/lib/Support/Unix/Signals.inc | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/llvm/lib/Support/Unix/Signals.inc b/llvm/lib/Support/Unix/Signals.inc index a4525a5..6cd38aa 100644 --- a/llvm/lib/Support/Unix/Signals.inc +++ b/llvm/lib/Support/Unix/Signals.inc @@ -78,6 +78,10 @@ #include <__le_cwi.h> #endif +#if defined(__linux__) +#include <sys/syscall.h> +#endif + using namespace llvm; static void SignalHandler(int Sig, siginfo_t *Info, void *); @@ -413,10 +417,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) { |