敢说敢作敢为, 无怨无恨无悔。这篇文章主要讲述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
也是一个好主意。推荐阅读
- Android - JNI // NDK无法找到SIGSEV
- 在Android上使用Address Sanitizer构建但使用CMake
- Android Studio NDK链接器错误未定义引用'cv :: _ OutputArray :: _ OutputArray(cv :: Mat&)'
- 在Android Studio 3.0中构建PIE和非PIE可执行文件
- JNI_OnLoad通常用于Android NDK吗()
- Android Studio 3.0.1在Android.mk中注释掉行
- Android Studio 3.0.1忽略Application.mk中的APP_ABI()
- Android NDK将参数传递给本机方法
- 有没有办法在Android NDK上使用__int128_t()