热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

AndroidJNI/NDK开发笔记:解决SIGSEGV崩溃信号处理未触发的问题

探讨在AndroidJNI/NDK环境中遇到的SIGSEGV崩溃问题,以及如何通过自定义信号处理器进行调试的方法。

本文旨在帮助开发者解决在Android JNI/NDK开发过程中遇到的SIGSEGV(Segmentation Fault)崩溃问题,特别是在应用程序从后台恢复后未能触发预期的信号处理机制的情况。


在使用Android原生C++代码时,发现应用程序在某些情况下,如从后台恢复至前台时,会发生SIGSEGV崩溃。为了更好地调试此类问题,尝试设置自定义信号处理器以捕获异常并打印堆栈信息。然而,尽管在JNI_OnLoad方法中注册了信号处理器,但在发生SIGSEGV时,该处理器并未被调用。

注册信号处理器的代码如下:

struct sigaction sighandler;
memset(&sighandler, 0, 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]);
}

其中,android_sigaction函数用于记录异常信息,并调用之前的信号处理器:

static struct sigaction old_sa[NSIG];
static void android_sigaction(int signal, siginfo_t *siginfo, void *context) {
MY_LOG("Sending PID: %ld, UID: %ld\n", (long)siginfo->si_pid, (long)siginfo->si_uid);
if (old_sa[signal].sa_handler != SIG_IGN && old_sa[signal].sa_handler != SIG_DFL) {
old_sa[signal].sa_handler(signal);
}
}

尽管如此,在应用从后台恢复时,android_sigaction仍未被调用。为测试信号处理器的有效性,尝试通过代码中的边界错误触发SIGSEGV,结果表明处理器能够正常工作。


解决方案

如果您使用的是Android 5.0或更高版本的设备,上述问题可能与Android的运行时环境ART有关。ART可能会覆盖或重定向标准的signal()sigaction()调用,导致自定义信号处理器无法按预期工作。为了解决这一问题,可以在调试阶段使用直接系统调用来注册信号处理器:

for(int signal : watched_signals) {
syscall(SYS_sigaction, signal, &sighandler, &old_sa[signal]);
}

这样可以确保信号处理器直接与内核交互,避免ART的影响。需要注意的是,这种方法仅适用于调试目的。若要在生产环境中使用,需确保新处理器能够正确处理原有的信号行为,以免影响应用的稳定性和兼容性。

此外,检查sigaction调用的返回值和errno变量也是诊断问题的重要步骤,有助于确定是否成功注册了信号处理器。



推荐阅读
  • 前文|功能型_品读鸿蒙HDF架构
    前文|功能型_品读鸿蒙HDF架构 ... [详细]
  • EasyMock实战指南
    本文介绍了如何使用EasyMock进行单元测试,特别是当测试对象的合作者依赖于外部资源或尚未实现时。通过具体的示例,展示了EasyMock在模拟对象行为方面的强大功能。 ... [详细]
  • 本文介绍了在Android项目中实现时间轴效果的方法,通过自定义ListView的Item布局和适配器逻辑,实现了动态显示和隐藏时间标签的功能。文中详细描述了布局文件、适配器代码以及时间格式化工具类的具体实现。 ... [详细]
  • 本文详细介绍了 Java 中 freemarker.ext.dom.NodeModel 类的 removeComments 方法,并提供了多个实际使用的代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • MySQL锁机制详解
    本文深入探讨了MySQL中的锁机制,包括表级锁、行级锁以及元数据锁,通过实例详细解释了各种锁的工作原理及其应用场景。同时,文章还介绍了如何通过锁来优化数据库性能,避免常见的并发问题。 ... [详细]
  • 本文详细介绍了如何正确安装Java EE SDK,并解决在安装过程中可能遇到的问题,特别是关于servlet代码在Apache Tomcat 10中无法运行的情况。 ... [详细]
  • 本文探讨了在QT框架中如何有效遍历文件内容,并解决了一个常见的错误,即文件内容读取为空时弹窗无法正常显示的问题。 ... [详细]
  • LCUI 2.1.0 版本现已推出,这是一个用 C 语言编写的图形用户界面开发库,适合创建轻量级的桌面应用程序。此次更新包括多项修复和功能增强,并正式宣布将启动 Android 支持的开发计划。 ... [详细]
  • 本文详细介绍了如何在现有的Android Studio项目中集成JNI(Java Native Interface),包括下载必要的NDK和构建工具,配置CMakeLists.txt文件,以及编写和调用JNI函数的具体步骤。 ... [详细]
  • 本文详细介绍了如何在Android应用中使用GridView组件以网格形式展示数据(如文本和图像)。通过行列布局,实现类似矩阵的数据展示效果。 ... [详细]
  • 本文介绍了一个项目中如何在Windows平台上实现多声道音频数据的采集,特别是针对DANTE音频接口的8路立体声音频通道。文章详细描述了使用Windows底层音频API进行音频采集的方法,并提供了一个具体的实现示例。 ... [详细]
  • 本文探讨了C++编程语言中声明与定义的区别,以及如何通过内部连接和外部连接来组织源文件,确保代码的正确链接与编译。文章详细解析了不同类型、变量、函数以及类的连接属性,并提供了实用的示例。 ... [详细]
  • Python基础教程:struct模块与格式化字符详解
    本文详细介绍了Python中struct模块的功能,以及如何利用格式化字符实现Python与C语言结构体之间的数据转换。文章通过具体实例讲解了struct模块的主要方法及其应用场景。 ... [详细]
  • C语言实现推箱子游戏的完整代码
    本文详细介绍了如何使用C语言在Linux环境下实现一个简单的推箱子游戏,包括游戏的基本规则、地图设计及代码实现。适合C语言初学者学习。 ... [详细]
  • 使用C# .NET构建UDP点对点聊天应用
    本文详细介绍如何利用C# .NET框架开发一个基于UDP协议的点对点聊天程序,包括客户端与服务器之间的连接建立、数据传输等核心功能。 ... [详细]
author-avatar
Ycandy
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有