From: jgu21 Date: Fri, 24 Jul 2015 05:40:33 +0000 (+0800) Subject: Register signal handler to kernel if not claimed X-Git-Tag: android-x86-7.1-r1~889^2~655^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=0c7c55c717e774598ebce25f662209e8db23b3c9;p=android-x86%2Fart.git Register signal handler to kernel if not claimed To set special handler for a signal, if the signal was not claimed before, the default handler in sigchain must be registerred for it before claimimg it in sigchain. Change-Id: I7ab74392cabb7f34af8ae038c90d20f0641b9d99 Signed-off-by: jgu21 --- diff --git a/sigchainlib/sigchain.cc b/sigchainlib/sigchain.cc index 1391d147a..8e9d421b3 100644 --- a/sigchainlib/sigchain.cc +++ b/sigchainlib/sigchain.cc @@ -337,14 +337,16 @@ extern "C" void SetSpecialSignalHandlerFn(int signal, SpecialSignalHandlerFn fn) // 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); + } } } diff --git a/test/115-native-bridge/expected.txt b/test/115-native-bridge/expected.txt index 464d2c887..372ecd048 100644 --- a/test/115-native-bridge/expected.txt +++ b/test/115-native-bridge/expected.txt @@ -61,3 +61,4 @@ Getting trampoline for Java_Main_testNewStringObject with shorty V. trampoline_Java_Main_testNewStringObject called! Getting trampoline for Java_Main_testSignal with shorty I. NB signal handler with signal 11. +NB signal handler with signal 4. diff --git a/test/115-native-bridge/nativebridge.cc b/test/115-native-bridge/nativebridge.cc index c8141a7fb..a6a6e08e2 100644 --- a/test/115-native-bridge/nativebridge.cc +++ b/test/115-native-bridge/nativebridge.cc @@ -200,8 +200,9 @@ static jint trampoline_Java_Main_testSignal(JNIEnv*, jclass) { #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'; @@ -209,6 +210,11 @@ static jint trampoline_Java_Main_testSignal(JNIEnv*, jclass) { // On other architectures we simulate SEGV. kill(getpid(), SIGSEGV); #endif + + // Test sigill + sigaction(SIGILL, &tmp, nullptr); + kill(getpid(), SIGILL); + return 1234; } @@ -385,27 +391,29 @@ extern "C" bool nb_is_compatible(uint32_t bridge_version ATTRIBUTE_UNUSED) { // 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(context); - struct sigcontext *sc = reinterpret_cast(&uc->uc_mcontext); - sc->arm_pc += 2; // Skip instruction causing segv. + struct ucontext *uc = reinterpret_cast(context); + struct sigcontext *sc = reinterpret_cast(&uc->uc_mcontext); + sc->arm_pc += 2; // Skip instruction causing segv & sigill. #elif defined(__aarch64__) - struct ucontext *uc = reinterpret_cast(context); - struct sigcontext *sc = reinterpret_cast(&uc->uc_mcontext); - sc->pc += 4; // Skip instruction causing segv. + struct ucontext *uc = reinterpret_cast(context); + struct sigcontext *sc = reinterpret_cast(&uc->uc_mcontext); + sc->pc += 4; // Skip instruction causing segv & sigill. #elif defined(__i386__) || defined(__x86_64__) - struct ucontext *uc = reinterpret_cast(context); - uc->CTX_EIP += 3; + struct ucontext *uc = reinterpret_cast(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;