// In case the chain isn't claimed, claim it for ourself so we can ensure the managed handler
// goes first.
if (!user_sigactions[signal].IsClaimed()) {
- struct sigaction tmp;
- tmp.sa_sigaction = sigchainlib_managed_handler_sigaction;
- sigemptyset(&tmp.sa_mask);
- tmp.sa_flags = SA_SIGINFO | SA_ONSTACK;
+ struct sigaction act, old_act;
+ act.sa_sigaction = sigchainlib_managed_handler_sigaction;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_SIGINFO | SA_ONSTACK;
#if !defined(__APPLE__) && !defined(__mips__)
- tmp.sa_restorer = nullptr;
+ act.sa_restorer = nullptr;
#endif
- user_sigactions[signal].Claim(tmp);
+ if (sigaction(signal, &act, &old_act) != -1) {
+ user_sigactions[signal].Claim(old_act);
+ }
}
}
#if !defined(__APPLE__) && !defined(__mips__)
tmp.sa_restorer = nullptr;
#endif
- sigaction(SIGSEGV, &tmp, nullptr);
+ // Test segv
+ sigaction(SIGSEGV, &tmp, nullptr);
#if defined(__arm__) || defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
// On supported architectures we cause a real SEGV.
*go_away_compiler = 'a';
// On other architectures we simulate SEGV.
kill(getpid(), SIGSEGV);
#endif
+
+ // Test sigill
+ sigaction(SIGILL, &tmp, nullptr);
+ kill(getpid(), SIGILL);
+
return 1234;
}
// 004-SignalTest.
static bool nb_signalhandler(int sig, siginfo_t* info ATTRIBUTE_UNUSED, void* context) {
printf("NB signal handler with signal %d.\n", sig);
+ if (sig == SIGSEGV) {
#if defined(__arm__)
- struct ucontext *uc = reinterpret_cast<struct ucontext*>(context);
- struct sigcontext *sc = reinterpret_cast<struct sigcontext*>(&uc->uc_mcontext);
- sc->arm_pc += 2; // Skip instruction causing segv.
+ struct ucontext *uc = reinterpret_cast<struct ucontext*>(context);
+ struct sigcontext *sc = reinterpret_cast<struct sigcontext*>(&uc->uc_mcontext);
+ sc->arm_pc += 2; // Skip instruction causing segv & sigill.
#elif defined(__aarch64__)
- struct ucontext *uc = reinterpret_cast<struct ucontext*>(context);
- struct sigcontext *sc = reinterpret_cast<struct sigcontext*>(&uc->uc_mcontext);
- sc->pc += 4; // Skip instruction causing segv.
+ struct ucontext *uc = reinterpret_cast<struct ucontext*>(context);
+ struct sigcontext *sc = reinterpret_cast<struct sigcontext*>(&uc->uc_mcontext);
+ sc->pc += 4; // Skip instruction causing segv & sigill.
#elif defined(__i386__) || defined(__x86_64__)
- struct ucontext *uc = reinterpret_cast<struct ucontext*>(context);
- uc->CTX_EIP += 3;
+ struct ucontext *uc = reinterpret_cast<struct ucontext*>(context);
+ uc->CTX_EIP += 3;
#else
- UNUSED(context);
+ UNUSED(context);
#endif
+ }
// We handled this...
return true;
}
static ::android::NativeBridgeSignalHandlerFn native_bridge_get_signal_handler(int signal) {
- // Only test segfault handler.
- if (signal == SIGSEGV) {
+ // Test segv for already claimed signal, and sigill for not claimed signal
+ if ((signal == SIGSEGV) || (signal == SIGILL)) {
return &nb_signalhandler;
}
return nullptr;