aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/Unix/Signals.inc
diff options
context:
space:
mode:
authorAlex Langford <alangford@apple.com>2025-07-09 14:53:15 -0700
committerGitHub <noreply@github.com>2025-07-09 14:53:15 -0700
commit9337594e3346e15b5bc90b5372b8b482aa5af37f (patch)
tree025a73485d3f1b05c11cb800cb2842d0645540a7 /llvm/lib/Support/Unix/Signals.inc
parent6d00c4297f6714c03ab10f57c10063ebd79264a1 (diff)
downloadllvm-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.inc21
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) {