Android Native 异常捕获库

Android Native 异常捕获库_android捕获native异常so库 可以使用ndk中的add2line工具根据pc值和带符号信息的so库,定位出具体代码行数。 阅读详情

现状

  • 发生native异常时,安卓系统会将native异常信息输出到logcat中,但是java层无法感知到native异常的发生,进而无法获取这些异常信息并上报到业务的异常监控系统。
  • 业务部门可以快速实现java层的异常监控系统(java层全局异常捕获的实现很简单),又或者业务部门已经实现了java层的异常监控系统,但没有覆盖到native层的异常捕获。
  • 安卓还可以接入Breakpad,其导出的minidump文件不仅体积小信息还全,但有两个问题:
    • 1.和现状第1点的问题相同。
    • 2.:需要拉取minidump文件并经过比较繁琐的步骤才可以得出有用的信息:
      • 启动时检测Breakpad是否有导出过minidump文件,有则说明发生过native异常。
      • 到客户现场,或者远程拉取minidump文件。
      • 编译出自己电脑的操作系统的minidump_stackwalk工具。
      • 使用minidump_stackwalk工具翻译minidump文件内容,例如拿到崩溃时的程序计数器寄存器内的值(下文称为pc值)。
      • 找到对应崩溃so库ABI的add2line工具,并根据上一步拿到的pc值定位出发生异常的代码行数。

整个步骤十分复杂和繁琐,且没有java层的crash线程栈信息,不利于java开发者快速定位调用native的代码。

设计意图

  1. 让java层有知悉native异常的通道:
    • java开发者可以在java代码中得到native异常的情况,进而对native异常做出反应,而不是再次启动后去检测Breakpad是否有导出过minidump文件。
  2. 增加信息的可用性,进而提升问题分析的效率:
    • 回调中提供naive异常信息、naive和java调用栈信息和minidump文件文件路径,这些信息可以直接通过业务部门的异常监控系统上报。

    • 划分为两个阶段解决问题,我预想是大部分都在阶段一解决了问题,而不需要再对minidump文件进行分析,总体来讲是提升了分析效率的:

      • 阶段一:有了java的调用栈和native的调用栈信息,大部分异常原因都可以快速定位并分析出来。
      • 阶段二:回调中也会提供minidump文件的存储路径,业务部门可以按需拉取。(这一步需要业务部门本身有拉取日志的功能,且需要按上文”现状部分进行操作”,较费时费力)
  3. 最少改动:
    • 让接入方不因为引入新功能而大量改动现有代码。例如:在native崩溃回调处,使用现有的java层异常监控系统上报native异常信息。
  4. 单一职责:
    • 只做native的crash捕获,不做系统内存情况、cpu使用率、系统日志等信息的采集功能。

整体流程

image.png

功能介绍

  • 保留breakpad导出minidump文件功能 (可选择是否启用)
  • 发生native异常时将异常信息、native层调用栈、java层的调用栈通过回调提供给开发者,将这些信息输出到控制台的效果如下:
2022-02-14 11:33:08.598 30228-30253/com.babyte.banativecrash E/crash:  
    /data/user/0/com.babyte.banativecrash/cache/f1474006-60ca-40f4-c9d8e89a-47e90c2e.dmp
2022-02-14 11:33:08.599 30228-30253/com.babyte.banativecrash E/crash:  
    Operating system: Android 28 Linux 4.4.146 #37 SMP PREEMPT Wed Jan 20 18:26:59 CST 2021
    CPU: aarch64 (8 core)
    
    Crash reason: signal 11(SIGSEGV) Invalid address
    Crash address: 0000000000000000
    Crash pc: 0000000000000650
    Crash so: /data/app/com.babyte.banativecrash-ptLzOQ_6UYz-W3Vgyact8A==/lib/arm64/libnative-lib.so(arm64)
    Crash method: _Z5Crashv
2022-02-14 11:33:08.602 30228-30253/com.babyte.banativecrash E/crash:  
    Thread[name:DefaultDispatch] (NOTE: linux thread name length limit is 15 characters)
    #00 pc 0000000000000650  /data/app/com.babyte.banativecrash-ptLzOQ_6UYz-W3Vgyact8A==/lib/arm64/libnative-lib.so (Crash()+20)
    #01 pc 0000000000000670  /data/app/com.babyte.banativecrash-ptLzOQ_6UYz-W3Vgyact8A==/lib/arm64/libnative-lib.so (Java_com_babyte_banativecrash_MainActivity_nativeCrash+20)
    #02 pc 0000000000565de0  /system/lib64/libart.so (offset 0xc1000) (art_quick_generic_jni_trampoline+144)
    #03 pc 000000000055cd88  /system/lib64/libart.so (offset 0xc1000) (art_quick_invoke_stub+584)
    #04 pc 00000000000cf740  /system/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200)
    #05 pc 00000000002823b8  /system/lib64/libart.so (offset 0xc1000) 
...
2022-02-14 11:33:08.603 30228-30253/com.babyte.banativecrash E/crash:  
    Thread[DefaultDispatcher-worker-1,5,main]
        at com.babyte.banativecrash.MainActivity.nativeCrash(Native Method)
        at com.babyte.banativecrash.MainActivity$onCreate$2$1.invokeSuspend(MainActivity.kt:39)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
    Thread[DefaultDispatcher-worker-2,5,main]
        at java.lang.Object.wait(Native Method)
        at java.lang.Thread.parkFor$(Thread.java:2137)
        at sun.misc.Unsafe.park(Unsafe.java:358)
        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:353)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.park(CoroutineScheduler.kt:795)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.tryPark(CoroutineScheduler.kt:740)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:711)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
... 

定位到so中具体代码行示例

可以使用ndk中的add2line工具根据pc值和带符号信息的so库,定位出具体代码行数。

例:从上文的异常信息中可以看到abi是aarch64,对应的so库abi是arm64,所以add2line的使用如下:

$ ./ndk/android-ndk-r16b/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-addr2line -Cfe ~/arm64-v8a/libnative-lib.so 0000000000000650 

输出结果如下:

Crash()
/Users/ba/AndroidStudioProjects/NativeCrash2Java/app/.cxx/cmake/debug/arm64-v8a/../../../../src/main/cpp/native-lib.cpp:6 

接入方式

根项目的build.gradle中:

allprojects {
    repositories {
        mavenCentral()//添加这一行
    }
} 

模块的build.gradle中:

dependencies {   
    //添加这一行,releaseVersionCode填最新的版本
	implementation 'io.github.BAByte:native-crash:releaseVersionCode' 
} 

初始化

两种模式可选:

//发生native异常时:回调异常信息并导出minidump到指定目录,
BaByteBreakpad.initBreakpad(this.cacheDir.absolutePath) { info:CrashInfo ->
    //格式化输出到控制台
    BaByteBreakpad.formatPrint(TAG, info)
}

//发生native异常时:回调异常信息
BaByteBreakpad.initBreakpad { info:CrashInfo ->
    //格式化输出到控制台
    BaByteBreakpad.formatPrint(TAG, info)
} 

致谢

  • 感谢google breakpad库提供的源码
  • 感谢腾讯bugly团队提供在发生异常时,native回调java层的思路
  • 感谢爱奇艺xCrash库源码中的dlopen思路

文末

我总结了一些Android核心知识点,以及一些最新的大厂面试题、知识脑图和视频资料解析。

需要的直接点击文末小卡片可以领取哦!我免费分享给你,以后的路也希望我们能一起走下去。(谢谢大家一直以来的支持,需要的自己领取)

**Android学习PDF+架构视频+面试文档+源码笔记**

部分资料一览:

  • 330页PDF Android学习核心笔记(内含8大板块)

  • Android学习的系统对应视频

  • Android进阶的系统对应学习资料

  • Android BAT大厂面试题(有解析)

领取地址:

【29】Android之学习native开发(一) jni、ndk、native 阅读详情

相关推荐

Android NativeCrash 捕获与解析,androidui设计原理

使用mk文件进行编译的时候,可以增加如下命令,也可以直接编译出strip的so -fvisibility=hidden 二、NE 捕获与解析 =========================================================================== NE解析顾名思议就是堆栈解析,当然所有的前提就是需要保存一份带符号表、也就是未被strip的so,如果你只有strip之后的so,那就无能为力了,堆栈基本无法还原了。 一般有以下三种方式可以捕获和还原堆栈。 2.1 l

m0_61362539的博客 715

安卓分层

Android的分4层,java应用程序,java框架,本地框架和java运行环境,Linux内核空间 Native层就是本地框架。Java应用程序无需过多解释,基本可以理解为各个App,由Java语言实现。 Java框架层就是常说的Framework,这层里东西很多也很复杂,比如说主要的一些系统服务如ActivityManagerService、PackageManagerService等,

s546725246的专栏 1223

针对Android的Crash监控, 崩溃分析---推荐Bugly

最近在做公司的一个项目时候,需要在项目中增加一个崩溃异常收集和分析的功能,传统的话应该就是Android提供的全局异常捕捉,然后在捕捉后进行记录上传和分析,但是这样去做大大的浪费了很多的人力物力,后来发现有一个挺好用的腾讯SDK----Bugly。    腾讯的Bugly,面向移动开发者提供专业的Crash监控,崩溃分析等质量跟踪服务,它支持Android和IOS,我的主要使用到Android的

litetaure的博客 3431

Android 平台 Native 代码的崩溃捕获机制及实现

在前一步,我们获取了奔溃时的pc值和各个寄存器的内容,通过SP和FP所限定的stack frame,就可以得到母函数的SP和FP,从而得到母函数的stack frame(PC,LR,SP,FP会在函数调用的第一时间压栈),以此追溯,即可得到所有函数的调用顺序。在我的实验中,在子进程或者信号处理函数中,经常无法回调给java层。下面是Google Breakpad的流程图,在新的进程中DoDump,使用ptrace解析crash进程的堆栈,同时信号处理程序等待子进程完成任务后,再调用旧的信号处理函数。

idaretobe的专栏 2862

Android平台Native代码的崩溃捕获机制及实现

在Android平台,nativecrash一直是crash里的大头。nativecrash具有上下文不全、出错信息模糊、难以捕捉等特点,比javacrash更难修复。所以一个合格的异常捕获组件也要能达到以下目的:支持在crash时进行更多扩展操作,如:1.打印logcat和应用日志2.上报crash次数3.对不同的crash做不同的恢复措施4.可以针对业务不断改进和适应其实3个方案在Android平台的实现原理都是基本一致的,综合考虑,可以基于coffeecatch改进。在Unix-like系统中,所有的崩溃都是编程错误或者硬件错误相关的,系统遇到不可恢复的错误时会触发崩溃机制让程序退出,如

避坑指南:DDR4内存条Margin测试Fail?从Intel RMT工具到PCB Layout的完整排错思路

本文深入探讨了DDR4内存条在Margin测试中Fail的完整排错思路,从Intel RMT工具分析到PCB Layout优化。通过实战案例,详细解析了信号完整性问题的诊断与解决方案,包括拓扑结构影响、传输线参数优化及HyperLynx仿真验证,为硬件设计工程师提供了宝贵的避坑指南。

weixin_42530458的博客 450

Android Native 异常捕获库_android捕获native异常so库(1)

保留breakpad导出minidump文件功能 (可选择是否启用)......我的面试经验分享可能不会去罗列太多的具体题目,因为我依然认为面试经验中最宝贵的不是那一个个具体的题目或者具体的答案,而是结束面试时,那一刻你的感受以及多天之后你的回味~很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,对此我整理了一些资料,需要的可以免费分享给大家在这里小编分享一份自己收录整理上述技术体系图相关的几十套。

2401_84519929的博客 678

STM32F103C8T6 + GY-906红外测温:手把手教你用CubeMX和HAL库搞定IIC驱动(附完整工程)

本文详细介绍了如何使用STM32F103C8T6和GY-906红外测温传感器(基于MLX90614芯片)实现非接触式温度测量。从STM32CubeMX工程创建、HAL库驱动适配到温度数据采集与处理,提供完整的开发流程和常见问题解决方案,帮助开发者快速掌握红外测温技术。

weixin_29188043的博客 254

Android 捕获native异常

7.1切换到Breakpad-master\tools\mac目录下,运行命令minidump_stackwalk C:\Users\86138\Desktop\apk\crashFiles\d09869f4-cdaf-4f03-85f57d8e-e4fd512b.dmp >carsh.txt。4.4编译,在\build\intermediates\cmake\debug\obj\目录下获取so库。4.2CMakeLists.txt设置和native-lib.cpp代码。*ptr = 12;

sunshine_0707的博客 1428

免安装版Notepad++终极配置:右键菜单+图标美化+多文件批量处理(2024新版)

本文详细介绍了如何为免安装版Notepad++进行终极配置,包括右键菜单添加、图标美化以及多文件批量处理功能。通过注册表编辑和高级定制,用户可以在便携版中实现与安装版相同的功能体验,同时保持系统整洁。特别适合开发者、系统管理员和效率追求者使用。

nut55的博客 830

坐标偏移不一致或瓦块重名的多个OSGB工程的融合

介绍如何使用实景三维小助手OSGBLab对坐标偏移不一致或瓦块重名的多个OSGB工程的融合

OSGBLab的博客 3232

xCrash捕获Native异常(一)

Native异常 android 开发过程中有时候需要使用JNI的方式调用C/C++的库。因此在调试的过程如果发现崩溃异常,如果能够获取C/C++ 的异常堆栈,则可以方便的确定哪一行代码出现了问题,方便快速的定位问题。 在捕获Native异常中,原理上面基本是采用linux的信号机制。 linux信号机制 关于Unix-like系统的信号机制可以参见《深入Linux内核》第4章 中断和异常 ;第1...

cxmfzu的博客 2392

从零到一:Mx_yolo本地训练与K210部署实战指南

本文详细介绍了从零开始进行Mx_yolo本地模型训练到K210部署的全流程实战指南。涵盖环境配置、数据准备、模型训练与调优、模型转换及K210部署等关键步骤,并提供了常见问题解决方案和性能优化技巧,帮助开发者高效完成AI模型在嵌入式设备的落地应用。

weixin_29081163的博客 252

Android 平台的Crash崩溃捕获-全

上层-java/kotlin: Android应用层java/kotlin的crash捕获相对容易。直接实现Thread.UncaughtExceptionHandler即可处理收集。Thread.UncaughtExceptionHandler:当某一线程因未捕获的异常而即将终止时,Java 虚拟机将使用 Thread.getUncaughtExceptionHandler() 查询该线程以获得其 UncaughtExceptionHandler 的线程,并调用处理程序的 uncaughtExcepti

Jason_Lee155的博客 5170

保姆级教程:用MATLAB搞定双目相机标定,从导入图片到参数解读全流程

本文提供了一份详细的MATLAB双目相机标定全流程指南,涵盖从图片准备到参数解读的每个环节。重点讲解了棋盘格选择、拍摄技巧、MATLAB工具箱设置及参数优化,帮助读者避免常见错误并提升标定精度。特别适合机器人导航、三维重建等领域的开发者。

weixin_33737134的博客 429

B3640 T3 句子反转

要求将这些单词倒序输出。而且对于每个单词,如果是小写词,应当转为大写;如果是大写词,应当转为小写;如果是自然数,应该倒转输出。给定一行句子,每个词之间用空格隔开,要么是全小写英文单词,要么是全大写英文单词,要么是自然数。第一次做的时候0分,两个小时没做出来。仅一行,表示程序对句子的处理结果。仅一行,即需要反转的句子。

小前日记 366

react-native-exception-handler源码解析:如何优雅拦截React Native崩溃

react-native-exception-handler是一个强大的React Native模块,它允许开发者注册全局错误处理器,捕获致命和非致命的未捕获异常,从而提升应用的稳定性和用户体验。 ## 为什么需要异常处理? 在React Native开发中,应用崩溃是影响用户体验的常见问题。默认情况下,应用崩溃时会直接退出或显示系统级错误,这对用户来说非常不友好。react-native-e

gitblog_00047的博客 542

RK3588高速接口实战-PCIE

摘要: RK3588的PCIe接口支持PCIe 3.0x4和PCIe 2.1x1/x2,具备Root Complex和Endpoint模式,适用于NVMe SSD、5G模块等高速设备。硬件设计需注意85Ω/100Ω阻抗匹配、220nF AC耦合电容及100MHz参考时钟。设备树需配置控制器节点、PHY模式和IOMMU映射(RC模式用iommu-map,EP模式用iommus)。调试时可通过lspci检查链路状态,dmesg查看训练日志,perf分析性能。常见问题包括设备识别失败(检查复位时序、PHY配置)、

weiyvyy的博客 504

Breakpad 简单使用

在Android日常开发中,我们肯定会遇到Crash,当Crash发生时我们应该尽可能详细的收集Crash信息,这样才会对我们定位问题时提供准确的信息。 对于Android开发中遇到的Crash,基本可以分为两类:Java Crash和Native Crash。 下面我们针对这两种Crash如何捕获进行简单的介绍。1.Java Crash捕获 相比于native crash,我们对于Java crash更为熟悉,在其发生时我们也相对容易对其信息进行捕获。 在Java中发生...

3791

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

为什么选择CoffeeCatch?轻量级信号捕获库的5大优势

CoffeeCatch是一款轻量级的原生POSIX信号捕获库,特别适用于Android/Dalvik平台上的JNI代码,能将致命信号转化为可恢复的异常,帮助开发者更优雅地处理程序崩溃问题。 ## 1. 极致轻量,资源占用极小 作为一款"tiny"信号处理库,CoffeeCatch的核心实现仅包含[coffeecatch.c](https://link.gitcode.com/i/f5235ca

gitblog_00782的博客 282

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

linux nefilter 框架,NE问题分析之框架

本文是NE问题分析的第一篇,将先对NE问题做一个简要说明Native application在Android软件架构里,这些应用程序组成了native layer,native layer里的应用程序崩溃统称为Native Exception,比如空指针,非法指针,程序跑飞,内存踩坏等,好比像windows下,程序崩溃弹出某某地址不能为read/write。图片.png总流程图原始的linux,对...

weixin_39861823的博客 363

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Android 下 Poco库的异常不能被catch

记一次Android项目中SDK中Poco异常无法捕获的问题,编译Poco库,打开了异常的选项:android.mk LOCAL_CPPFLAGS := -frtti -fexceptions 在JNI的动态库中有异常抛出时无法正常捕获,会让程序崩溃。 解决方法:在使用Poco库的异常时,需要在正常捕获过一次异常才能让Poco库的异常被正常捕获。 对于这个问题是解决了,但是并没有弄明白,看了源码也没发现问题,有知道的朋友可以在下方留言探讨下。 本想着是不是android的SDK中都无法正常捕获

caifubing的博客 731

安卓捕获RuntimeException,ANR,Native信号异常

三大崩溃 众所周知,安卓端有三大崩溃,都会造成应用崩掉,分别是 RuntimeException java端的运行时异常.比如一些空指针之类的,发生时应用会崩溃. ANR 安卓为了用户体验设的保护机制,在应用在主线程做耗时操作的时候,长时间无响应会产生,一个问用户是否要继续等待的选择框,若用户选择关闭,或者长时间不选择,都会造成应用关闭. Native信号异常 当我们的代码导...

snail201211的博客 897
上一篇: Android Dex文件详解
下一篇: Android11 车载 Framework PBAP同步电话簿如何添加姓名全拼和首字母的需求
网络安全-XG
博客等级 码龄5年 1万+粉丝 2752原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值