Android - JNI / NDK - 与SIGSEV崩溃 - 未触发信号处理

敢说敢作敢为, 无怨无恨无悔。这篇文章主要讲述Android - JNI / NDK - 与SIGSEV崩溃 - 未触发信号处理相关的知识,希望能为你提供帮助。
我有android原生C ++代码。但是,有时当我将应用程序发送到后台并返回时,它会与SIGSEGV崩溃。我想使用自己的信号处理和打印堆栈跟踪来调试它,但是,当发生此错误时,我的信号处理根本不会被触发。
对于JNI_OnLoad方法,我添加了:

struct sigaction sighandler; memset (& sighandler, '', sizeof(sighandler)); sighandler.sa_sigaction = & android_sigaction; sighandler.sa_flags = SA_SIGINFO; int watched_signals[] = { SIGABRT, SIGILL, SIGSEGV, SIGINT, SIGKILL }; for(int signal : watched_signals) { sigaction(signal, & sighandler, & old_sa[signal]); }

我有:
static struct sigaction old_sa[NSIG]; static void android_sigaction(int signal, siginfo_t *siginfo, void *context) { MY_LOG("Sending PID: %ld, UID: %ld ", (long)siginfo-> si_pid, (long)siginfo-> si_uid); old_sa[signal].sa_handler(signal); }

但是,当应用程序从后台运行时,android_sigaction永远不会因错误而受到攻击。我试图在代码中创建bug(在数组边界外编写),使用按钮按钮触发它并正确调用回调。到底是怎么回事?
答案假设您使用的是Android 5.0+设备,您的问题可能是由ART造成的。它暴露了自己的signal()sigaction(),因此它有机会窃取信号并将其传递到其他地方。出于调试目的,您可以尝试直接系统调用:
for(int signal : watched_signals) { syscall(_NR_sigaction, signal, & sighandler, & old_sa[signal]); }

所以现在你的处理程序直接进入内核,ART不应该改变它。当然它只适用于调试。如果你想用这个来做刺激 - 你需要开发一些能够尊重前一个处理程序的逻辑。
【Android - JNI / NDK - 与SIGSEV崩溃 - 未触发信号处理】附:还检查返回值和errno也是一个好主意。

    推荐阅读