Commit 6631fb24 by Nicolas Capens

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/5345Reviewed-by: 's avatarGreg Hartman <ghartman@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com> Tested-by: 's avatarNicolas Capens <capn@google.com>
parent 8487119f
......@@ -268,6 +268,7 @@ void CrashRecoveryContext::Enable() {
gCrashRecoveryEnabled = true;
#ifdef ENABLE_SIGNAL_OVERRIDES
// Setup the signal handler.
struct sigaction Handler;
Handler.sa_handler = CrashRecoverySignalHandler;
......@@ -277,6 +278,7 @@ void CrashRecoveryContext::Enable() {
for (unsigned i = 0; i != NumSignals; ++i) {
sigaction(Signals[i], &Handler, &PrevActions[i]);
}
#endif
}
void CrashRecoveryContext::Disable() {
......@@ -287,9 +289,11 @@ void CrashRecoveryContext::Disable() {
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
......
......@@ -308,6 +308,7 @@ Program::Wait(const sys::Path &path,
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 @@ Program::Wait(const sys::Path &path,
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 @@ Program::Wait(const sys::Path &path,
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.
......
......@@ -57,7 +57,7 @@ static const int KillSigs[] = {
, SIGSYS
#endif
#ifdef SIGXCPU
//, SIGXCPU
, SIGXCPU
#endif
#ifdef SIGXFSZ
, SIGXFSZ
......@@ -95,11 +95,13 @@ static void RegisterHandler(int Signal) {
}
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() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment