热门标签 | 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变量也是诊断问题的重要步骤,有助于确定是否成功注册了信号处理器。



推荐阅读
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • Android 渐变圆环加载控件实现
    本文介绍了如何在 Android 中创建一个自定义的渐变圆环加载控件,该控件已在多个知名应用中使用。我们将详细探讨其工作原理和实现方法。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 本文介绍如何使用Objective-C结合dispatch库进行并发编程,以提高素数计数任务的效率。通过对比纯C代码与引入并发机制后的代码,展示dispatch库的强大功能。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 本文介绍如何使用 NSTimer 实现倒计时功能,详细讲解了初始化方法、参数配置以及具体实现步骤。通过示例代码展示如何创建和管理定时器,确保在指定时间间隔内执行特定任务。 ... [详细]
  • 本文介绍如何在 Android 中通过代码模拟用户的点击和滑动操作,包括参数说明、事件生成及处理逻辑。详细解析了视图(View)对象、坐标偏移量以及不同类型的滑动方式。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 在金融和会计领域,准确无误地填写票据和结算凭证至关重要。这些文件不仅是支付结算和现金收付的重要依据,还直接关系到交易的安全性和准确性。本文介绍了一种使用C语言实现小写金额转换为大写金额的方法,确保数据的标准化和规范化。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本章将深入探讨移动 UI 设计的核心原则,帮助开发者构建简洁、高效且用户友好的界面。通过学习设计规则和用户体验优化技巧,您将能够创建出既美观又实用的移动应用。 ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
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社区 版权所有