Disable all LLVM signal handlers.
This fixes issues on Android where applications use these signals in their
normal course of execution. The Mono C# framework uses SIGXCPU for garbage
collection, and ART uses SIGSEGV, SIGQUIT, and SIGUSR1.
Bug 27555932
Change-Id: I4977b8f0419da660a57a8eeef20a7fe747921a63
Reviewed-on: https://swiftshader-review.googlesource.com/5345
Reviewed-by: Greg Hartman <ghartman@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
diff --git a/third_party/LLVM/lib/Support/CrashRecoveryContext.cpp b/third_party/LLVM/lib/Support/CrashRecoveryContext.cpp
index 263114c..e667931 100644
--- a/third_party/LLVM/lib/Support/CrashRecoveryContext.cpp
+++ b/third_party/LLVM/lib/Support/CrashRecoveryContext.cpp
@@ -268,6 +268,7 @@
gCrashRecoveryEnabled = true;
+#ifdef ENABLE_SIGNAL_OVERRIDES
// Setup the signal handler.
struct sigaction Handler;
Handler.sa_handler = CrashRecoverySignalHandler;
@@ -277,6 +278,7 @@
for (unsigned i = 0; i != NumSignals; ++i) {
sigaction(Signals[i], &Handler, &PrevActions[i]);
}
+#endif
}
void CrashRecoveryContext::Disable() {
@@ -287,9 +289,11 @@
gCrashRecoveryEnabled = false;
+#ifdef ENABLE_SIGNAL_OVERRIDES
// Restore the previous signal handlers.
for (unsigned i = 0; i != NumSignals; ++i)
sigaction(Signals[i], &PrevActions[i], 0);
+#endif
}
#endif
diff --git a/third_party/LLVM/lib/Support/Unix/Program.inc b/third_party/LLVM/lib/Support/Unix/Program.inc
index 0197c5f..0d86b0f 100644
--- a/third_party/LLVM/lib/Support/Unix/Program.inc
+++ b/third_party/LLVM/lib/Support/Unix/Program.inc
@@ -308,6 +308,7 @@
return -1;
}
+#ifdef ENABLE_SIGNAL_OVERRIDES
// Install a timeout handler. The handler itself does nothing, but the simple
// fact of having a handler at all causes the wait below to return with EINTR,
// unlike if we used SIG_IGN.
@@ -318,12 +319,14 @@
sigaction(SIGALRM, &Act, &Old);
alarm(secondsToWait);
}
+#endif
// Parent process: Wait for the child process to terminate.
int status;
uint64_t pid = reinterpret_cast<uint64_t>(Data_);
pid_t child = static_cast<pid_t>(pid);
- while (waitpid(pid, &status, 0) != child)
+ while (waitpid(pid, &status, 0) != child) {
+#ifdef ENABLE_SIGNAL_OVERRIDES
if (secondsToWait && errno == EINTR) {
// Kill the child.
kill(child, SIGKILL);
@@ -339,16 +342,21 @@
MakeErrMsg(ErrMsg, "Child timed out", 0);
return -2; // Timeout detected
- } else if (errno != EINTR) {
+ } else
+#endif
+ if (errno != EINTR) {
MakeErrMsg(ErrMsg, "Error waiting for child process");
return -1;
}
+ }
+#ifdef ENABLE_SIGNAL_OVERRIDES
// We exited normally without timeout, so turn off the timer.
if (secondsToWait) {
alarm(0);
sigaction(SIGALRM, &Old, 0);
}
+#endif
// Return the proper exit status. Detect error conditions
// so we can return -1 for them and set ErrMsg informatively.
diff --git a/third_party/LLVM/lib/Support/Unix/Signals.inc b/third_party/LLVM/lib/Support/Unix/Signals.inc
index b0321fd..f2f5ff7 100644
--- a/third_party/LLVM/lib/Support/Unix/Signals.inc
+++ b/third_party/LLVM/lib/Support/Unix/Signals.inc
@@ -57,7 +57,7 @@
, SIGSYS
#endif
#ifdef SIGXCPU
- //, SIGXCPU
+ , SIGXCPU
#endif
#ifdef SIGXFSZ
, SIGXFSZ
@@ -95,11 +95,13 @@
}
static void RegisterHandlers() {
+#ifdef ENABLE_SIGNAL_OVERRIDES
// If the handlers are already registered, we're done.
if (NumRegisteredSignals != 0) return;
std::for_each(IntSigs, IntSigsEnd, RegisterHandler);
std::for_each(KillSigs, KillSigsEnd, RegisterHandler);
+#endif
}
static void UnregisterHandlers() {