Android NDK 中堆栈日志 add2line 的分析实践

news2025/4/27 16:35:27

文章目录

  • 目的
  • 常用的辅助工具
  • 分析步骤
  • 参考

目的

Android NDK 中出现的 crash 日志分析定位,使用 addr2line 对库中定位so 动态库崩溃位置,定位到某个函数的具体的代码行。

常用的辅助工具

add2line,objdump,ndkstack 等等。本文主要介绍 NDK 环境中的 add2line如何使用。

Addr2line 工具(它是标准的 GNU Binutils 中的一部分)是一个可以将指令的地址和可执行映像转换成文件名、函数名和源代码行数的工具。
一般适用于 debug 版本或带有 symbol 信息的库。

分析步骤

  1. 找到ndk中安装目录下的 addr2line.exe

    示例如下:安装了NDK后的某个目录。
    在这里插入图片描述

    第一个就是我们需要的命令,不过名字太长了,使用时不太方便,于是我就 copy 一个放到最后,并简短的命令一下为addr2line

  2. 然后在 windows 中添加系统环境下,方便我们直接调用该命令。

  3. 抓取日志并找到关键日志信息。

    Android Studio中的日志不容易抓全,容易一闪而过。可以用bat 命令来抓。

    参考命令如下:

    @echo off

    echo wait device
    adb wait-for-device

    echo loging
    adb logcat -v time >C:\Users\DELL\Desktop\log\error.log

    pause

    获取崩溃产生的记录堆栈信息的墓碑文件tombstone。 logcat 错误日志如下:

    12-22 23:44:46.790 I/crash_dump64(12441): obtaining output fd from tombstoned, type: kDebuggerdTombstone
    12-22 23:44:46.790 I//system/bin/tombstoned( 1063): received crash request for pid 12359
    12-22 23:44:46.792 I/crash_dump64(12441): performing dump of process 12359 (target tid = 12359)
    12-22 23:44:46.794 F/DEBUG (12441): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    12-22 23:44:46.794 F/DEBUG (12441): Build fingerprint: ‘PANCAKEXR/PANCAKE_1/PANCAKE_1:10/QKQ1.201018.002/11:userdebug/test-keys’
    12-22 23:44:46.794 F/DEBUG (12441): Revision: ‘0’
    12-22 23:44:46.794 F/DEBUG (12441): ABI: ‘arm64’
    12-22 23:44:46.794 F/DEBUG (12441): Timestamp: 2022-12-22 23:44:46+0800
    12-22 23:44:46.794 F/DEBUG (12441): pid: 12359, tid: 12359, name: om.ssnwt.camera >>> com.ssnwt.camera <<<
    12-22 23:44:46.794 F/DEBUG (12441): uid: 10105
    12-22 23:44:46.794 F/DEBUG (12441): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
    12-22 23:44:46.794 F/DEBUG (12441): Cause: null pointer dereference
    12-22 23:44:46.794 F/DEBUG (12441): x0 0000007238370ccb x1 000000000000002f x2 0000000000000001 x3 0000007238370ccb
    12-22 23:44:46.794 F/DEBUG (12441): x4 005b257300000000 x5 0000008000000000 x6 1246040000000000 x7 0000000080044612
    12-22 23:44:46.794 F/DEBUG (12441): x8 0000007ff1cc93d0 x9 0000000000000000 x10 000000000000002f x11 0000000000000038
    12-22 23:44:46.794 F/DEBUG (12441): x12 0000000000000020 x13 0000000000000002 x14 0000000000000008 x15 000047544b6a35cd
    12-22 23:44:46.794 F/DEBUG (12441): x16 000000723837eb60 x17 00000073231c2b2c x18 000000729694e210 x19 0000007ff1cc92c0
    12-22 23:44:46.794 F/DEBUG (12441): x20 0000000000000000 x21 0000007325a0cc00 x22 0000007ff1cc9c10 x23 0000007297e12756
    12-22 23:44:46.794 F/DEBUG (12441): x24 0000000000000008 x25 0000007325c9e020 x26 0000007325a0ccb0 x27 0000000000000002
    12-22 23:44:46.794 F/DEBUG (12441): x28 0000007ff1cc99a0 x29 0000007ff1cc98e0
    12-22 23:44:46.794 F/DEBUG (12441): sp 0000007ff1cc92c0 lr 0000007238353544 pc 0000007238353578
    12-22 23:44:46.873 D/InvisionDisplayManagerService( 1375): applySetPowerState mPowerOn = true
    12-22 23:44:46.874 E/InvisionDisplayManagerService( 1375): Failed to applySetPowerState ivslam = null
    12-22 23:44:46.925 F/DEBUG (12441):
    12-22 23:44:46.925 F/DEBUG (12441): backtrace:
    12-22 23:44:46.926 F/DEBUG (12441): #00 pc 0000000000013578 /data/app/com.ssnwt.camera-hfkg6MwSsTZphlAHWYVnzw==/base.apk!libndk_camera.so (offset 0x651000) (NdkCamera::open(char const*, void ()(char const, unsigned char*, int, int, int, int, long), ANativeWindow**, int)+460) (BuildId: 953887cae84ec067885a1b0c7315d189686e353d)
    12-22 23:44:46.926 F/DEBUG (12441): #01 pc 0000000000011980 /data/app/com.ssnwt.camera-hfkg6MwSsTZphlAHWYVnzw==/base.apk!libndk_camera.so (offset 0x651000) (Java_com_ssnwt_camera_NativeCameraActivity_openMultiCamera+468) (BuildId: 953887cae84ec067885a1b0c7315d189686e353d)
    12-22 23:44:46.926 F/DEBUG (12441): #02 pc 000000000013f350 /apex/com.android.runtime/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: 8fb5976d4465346647f3e5e5870bdc7a)
    12-22 23:44:46.926 F/DEBUG (12441): #03 pc 0000000000136334 /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: 8fb5976d4465346647f3e5e5870bdc7a)
    12-22 23:44:46.926 F/DEBUG (12441): #04 pc 0000000000144fec /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+244) (BuildId: 8fb5976d4465346647f3e5e5870bdc7a)
    12-22 23:44:46.926 F/DEBUG (12441): #05 pc 00000000002e204c /apex/com.android.runtime/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+384) (BuildId: 8fb5976d4465346647f3e5e5870bdc7a)
    12-22 23:44:46.926 F/DEBUG (12441): #06 pc 00000000002dd2ac /apex/com.android.runtime/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+892) (BuildId: 8fb5976d4465346647f3e5e5870bdc7a)
    12-22 23:44:46.926 F/DEBUG (12441): #07 pc 00000000005a1538 /apex/com.android.runtime/lib64/libart.so (MterpInvokeDirect+424) (BuildId: 8fb5976d4465346647f3e5e5870bdc7a)
    12-22 23:44:46.926 F/DEBUG (12441): #08 pc 0000000000130914 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_direct+20) (BuildId: 8fb5976d4465346647f3e5e5870bdc7a)
    12-22 23:44:46.926 F/DEBUG (12441): #09 pc 0000000000003648 /data/app/com.ssnwt.camera-hfkg6MwSsTZphlAHWYVnzw==/base.apk (com.ssnwt.camera.NativeCameraActivity.lambda$initCameraView 2 2 2NativeCameraActivity+4)
    12-22 23:44:46.926 F/DEBUG (12441): #10 pc 000000000059f4d0 /apex/com.android.runtime/lib64/libart.so (MterpInvokeVirtual+1352) (BuildId: 8fb5976d4465346647f3e5e5870bdc7a)
    12-22 23:44:46.926 F/DEBUG (12441): #11 pc 0000000000130814 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: 8fb5976d4465346647f3e5e5870bdc7a)
    12-22 23:44:46.926 F/DEBUG (12441): #12 pc 0000000000002538 /data/app/com.ssnwt.camera-hfkg6MwSsTZphlAHWYVnzw==/base.apk (com.ssnwt.camera.-$ L a m b d a Lambda LambdaNativeCameraActivityKaTeX parse error: Expected 'EOF', got '#' at position 80: …(12441): #̲13 pc 000000000…MethodAndArgsCaller.run+22)
    12-22 23:44:46.926 F/DEBUG (12441): #41 pc 00000000002b3360 /apex/com.android.runtime/lib64/libart.so (_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_6JValueEbb.llvm.12500273830171183841+240) (BuildId: 8fb5976d4465346647f3e5e5870bdc7a)
    12-22 23:44:46.926 F/DEBUG (12441): #42 pc 0000000000590778 /apex/com.android.runtime/lib64/libart.so (artQuickToInterpreterBridge+1032) (BuildId: 8fb5976d4465346647f3e5e5870bdc7a)
    12-22 23:44:46.926 F/DEBUG (12441): #43 pc 000000000013f468 /apex/com.android.runtime/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: 8fb5976d4465346647f3e5e5870bdc7a)
    12-22 23:44:46.926 F/DEBUG (12441): #44 pc 00000000009b947c /system/framework/arm64/boot-framework.oat (com.android.internal.os.ZygoteInit.main+2076) (BuildId: 487da90bd032b6e46119f4e28971201c8f9f3457)
    12-22 23:44:46.926 F/DEBUG (12441): #45 pc 00000000001365b8 /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: 8fb5976d4465346647f3e5e5870bdc7a)
    12-22 23:44:46.926 F/DEBUG (12441): #46 pc 000000000014500c /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+276) (BuildId: 8fb5976d4465346647f3e5e5870bdc7a)
    12-22 23:44:46.926 F/DEBUG (12441): #47 pc 00000000004af0e4 /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104) (BuildId: 8fb5976d4465346647f3e5e5870bdc7a)
    12-22 23:44:46.926 F/DEBUG (12441): #48 pc 00000000004aecd4 /apex/com.android.runtime/lib64/libart.so (art::InvokeWithVarArgs(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+408) (BuildId: 8fb5976d4465346647f3e5e5870bdc7a)
    12-22 23:44:46.926 F/DEBUG (12441): #49 pc 00000000003b9df4 /apex/com.android.runtime/lib64/libart.so (art::JNI::CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, std::__va_list)+624) (BuildId: 8fb5976d4465346647f3e5e5870bdc7a)
    12-22 23:44:46.926 F/DEBUG (12441): #50 pc 00000000000c199c /system/lib64/libandroid_runtime.so (_JNIEnv::CallStaticVoidMethod(_jclass*, _jmethodID*, …)+116) (BuildId: a13dc1a4db7d246c6df31ff4e581e460)
    12-22 23:44:46.926 F/DEBUG (12441): #51 pc 00000000000c4878 /system/lib64/libandroid_runtime.so (android::AndroidRuntime::start(char const*, android::Vectorandroid::String8 const&, bool)+776) (BuildId: a13dc1a4db7d246c6df31ff4e581e460)
    12-22 23:44:46.926 F/DEBUG (12441): #52 pc 00000000000035b0 /system/bin/app_process64 (main+1376) (BuildId: 1a86d090ff0d3dd5f5a671601a88a247)
    12-22 23:44:46.926 F/DEBUG (12441): #53 pc 000000000007e898 /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+108) (BuildId: 21847aa9757f000b0461310a9f5e6e51)
    12-22 23:44:46.958 D/SVR_AndroidInterface(12313): Android interface branch: master, version code: 20, version name: 1.0.20-6d81be3

部分信息展示了出错时的运行状态, 当前中断原因是收到SIGSEGV(通常 crash 也都是因为收到这个信号,也有少数是因为 SIGFPE,即除0操作)。
错误码是SEGV_MAPERR,常见的段错误。然后出错地址为 0000000000013578

说明:我们常见的信号有下面这些:

信号码值描述
SIGILL4非法指令,例如损坏的可执行文件或代码区损坏
SIGABRT6通过C函数abort()发送;为assert()使用
SIGBUS7不存在的物理地址,更多为硬件或系统引起
SIGFPE8浮点数运算错误,如除0操作
SIGKILL9迅速完全终止进程;不能被捕获
SIGSEGV11段地址错误,例如空指针、野指针、数组越界等
  1. 最后在堆栈信息中找到 addr 表示栈地址。执行命令,示例如下:
C:\Users\DELL>addr2line.exe  -C -f -e E:\demo\India\CameraTest\app\build\intermediates\cmake\debug\obj\arm64-v8a\libndk_camera.so 0000000000013578
NdkCamera::open(char const*, void (*)(char const*, unsigned char*, int, int, int, int, long), ANativeWindow**, int)
E:/demo/India/CameraTest/app/src/main/cpp/NdkCamera.cpp:77

于是问题得到了定位,在 NdkCamera.cpp:77 第 77行的代码有问题,引发了 crash。 于时反向定位去进一步分析。

注意点: so 文件需要用 debug 中的 so 文件, 不要用 dubug.apk 中解压后的 so 文件, 不然会出现???.无法识别到。

命令的参数说明:

参数
-a --addresses:在函数名、文件和行号信息之前,显示地址,以十六进制形式。
-b --target=<bfdname>:指定目标文件的格式为bfdname。
-e --exe=<executable>:指定需要转换地址的可执行文件名。
-i --inlines : 如果需要转换的地址是一个内联函数,则输出的信息包括其最近范围内的一个非内联函数的信息。
-j --section=<name>:给出的地址代表指定section的偏移,而非绝对地址。
-p --pretty-print:使得该函数的输出信息更加人性化:每一个地址的信息占一行。
-s --basenames:仅仅显示每个文件名的基址(即不显示文件的具体路径,只显示文件名)。
-f --functions:在显示文件名、行号输出信息的同时显示函数名信息。
-C --demangle[=style]:将低级别的符号名解码为用户级别的名字。 // 注意此处需要大写
-h --help:输出帮助信息。
-v --version:输出版本号。

参考

Android Native Crash 分析指南

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/112236.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文深度揭开Redis的磁盘持久化机制

前言 Redis 是内存数据库&#xff0c;数据都是存储在内存中&#xff0c;为了避免进程退出导致数据的永久丢失&#xff0c;需要定期将 Redis 中的数据以数据或命令的形式从内存保存到本地磁盘。当下次 Redis 重启时&#xff0c;利用持久化文件进行数据恢复。Redis 提供了 RDB 和…

在linux上安装并初始化配置MariaDB支持远程登录

在linux上安装并初始化配置MariaDB支持远程登录一、环境准备二、启动MariaDB三、初始化MariaDB四、配置远程访问五、补充一些额外的MySql用户赋权限的语句一、环境准备 本文环境是Redhat7上自带的MariaDB, 在安装redhat系统时已经自动安装好了&#xff0c;如果需要自行安装的话…

Selenium 常用函数总结

Seleninum作为自动化测试的工具&#xff0c;自然是提供了很多自动化操作的函数&#xff0c; 下面列举下个人觉得比较常用的函数&#xff0c;更多可见官方文档&#xff1a; 官方API文档&#xff1a; http://seleniumhq.github.io/selenium/docs/api/py/api.html 1) 定位元素 f…

【源码共读】axios的46个工具函数

所有工具函数 还是老样子&#xff0c;先看看axios的工具函数有哪些&#xff0c;先心里有个印象&#xff0c;然后再逐个分析。 直接拉到最下面&#xff0c;可以看到axios的工具函数都是统一导出的&#xff1a; export default {isArray, // 判断是否是数组isArrayBuffer, // …

[机缘参悟-95] :不同人生和社会问题的本质

事情的本质是物极必反&#xff08;轮回、周期&#xff09; 社会的本质是优胜劣汰&#xff08;迭代、发展&#xff09; 道德的本质是伦理秩序&#xff08;未定、秩序&#xff09; 战争的本质是资源占用&#xff08;弱肉、强食&#xff09; 商业的本质是价值交换 金钱的本质…

同事这样用Redis,把我害惨了

首先说下问题现象&#xff1a;内网sandbox环境API持续1周出现应用卡死&#xff0c;所有api无响应现象 刚开始当测试抱怨环境响应慢的时候 &#xff0c;我们重启一下应用&#xff0c;应用恢复正常&#xff0c;于是没做处理。但是后来问题出现频率越来越频繁&#xff0c;越来越多…

MySQL实现主从复制(Windows)的明细操作步骤

文章目录一、教学视频地址二、设计思路三、具体步骤一、教学视频地址 视频地址&#xff1a;视频链接 二、设计思路 准备两个5.7版本的MySQL&#xff0c;一个用作主数据库&#xff0c;另一个用作从数据库。 把主数据库做为写入数据库&#xff0c;从数据库作为读数据库。 三…

【云原生 Kubernetes】基于 KubeAdmin 搭建k8s集群

一、前言 在上一篇&#xff0c;我们基于minikube搭建了一个单节点的k8s集群&#xff0c;作为学习和练习使用的话问题不大&#xff0c;但如果想深入学习和了解k8s的相关技术体系&#xff0c;还是需要搭建真正的集群才能更接近生产环境的应用&#xff0c;本篇将基于KubeAdmin&…

深度学习炼丹-数据预处理和增强

前言一&#xff0c;Normalization 概述 1.1&#xff0c;Normalization 定义1.2&#xff0c;什么情况需要 Normalization1.3&#xff0c;Data Normalization 方法1.4&#xff0c;示例代码 二&#xff0c;normalize images 2.1&#xff0c;图像 normalization 定义2.2&#xff0c…

Spring-Cloud-Gateway-07

前言 1、什么是网关 网关是微服务最边缘的服务&#xff0c;直接暴露给用户&#xff0c;用来做用户和微服务的桥梁 没有网关&#xff1a;客户端直接访问我们的微服务&#xff0c;会需要在客户端配置很多的ip&#xff1a;port&#xff0c;如果user-service并发比较大&#xff0c…

深度学习YoloV3案例

目录1 数据获取2 TFrecord文件2.1 什么是TFrecord文件2.2 将数据转换为TFRecord文件2.3 读取TFRecord文件2.4 数据处理3 模型构建4 模型训练4.1 损失函数的计算4.2 正负样本的设定4.3 模型训练4.3.1 获取数据集4.3.2 加载模型4.3.3 模型训练5 模型预测6 总结1 数据获取 根据要…

计算机工作原理简单介绍

文章目录一、冯诺依曼体系结构二、CPU基本工作流程CPU工作流程三、操作系统操作系统的基本功能四、进程&#xff08;process&#xff09;/任务&#xff08;task&#xff09;操作系统如何管理进程描述一个进程&#xff08;进程的相关属性&#xff09;组织若干进程CPU的分配内存的…

推荐系统,计算广告模型论文,代码与数据集汇总

Rec-Models 更多细节参考项目&#xff1a;https://github.com/JackHCC/Rec-Models https://github.com/JackHCC/Rec-Models &#x1f4dd; Summary of recommendation, advertising and search models. Recall Papers PaperResourceOthers[2019阿里SDM模型] SDM: Sequen…

Zebec Chain缘何能成为新晋应用链,熊市下又为何值得我们关注?

流支付生态 Zebec 正处于发展的火热阶段&#xff0c;Zebec此前于12月20日举办的为期3天的Web3.0 TechHive Summit 2022 大会&#xff0c;目前已经落幕&#xff0c;此次大会参会项目多达34个囊括了公链、钱包、DID、GameFi等多个主流行业赛道&#xff0c;并围绕行业安全、发展趋…

ConvLSTM时空预测实战代码详解

写在前面 时空预测是很多领域都存在的问题&#xff0c;不同于时间序列&#xff0c;时空预测不仅需要探究时间的变化&#xff0c;也需要关注空间的变化。许多预测问题都只片面的关注时间问题&#xff0c;如预测某人未来3年患某种病的概率&#xff0c;食堂就餐人数等&#xff0c…

CSS--圆角边框

单独对四个角进行设置&#xff1a; boder-top-left-radius&#xff1a;30px&#xff1b; //左上角 boder-top-right-radius&#xff1a;30px&#xff1b; //右上角 boder-bottom-left-radius&#xff1a;30px&#xff1b; //右下角 boder-bottom-right-radius&#xff1a;30px&…

群晖 Sonology NAS DS920+ 拆机装机方法

文章内容&#xff1a;群晖 Sonology NAS DS920 拆机方法 关键词组&#xff1a;群晖&#xff0c;Sonology, nas, ds920, 拆机, 外壳 使用软件&#xff1a;无 虚拟环境&#xff1a;无 操作系统&#xff1a;无 目录一、事件起因三、拆装机方法一、事件起因 起初&#xff0c;由于机…

OpenCV环境下实现图像任意角度旋转的原理及代码

OpenCV环境下实现图像任意角度旋转的原理及代码 实现图像任意角度旋转的原理如下&#xff1a; Step01-把图像原点从左上角转换到旋转中心点。 Step02-利用极坐标系计算出旋转后各点的坐标。 Step03-确定旋转后图像的左边界、右边界、上边界、下边界&#xff0c;进而得出旋转后…

计数排序 [数据结构与算法][Java]

计数排序 计数排序和基数排序都是桶排序的一种应用 适用场景: 量大但是范围小 比如对10000个数进行排序, 但是这10000个数中只有10种数字(0 - 9)典型题目: 某大型企业数万名员工年龄排序如何快速得知高考名次(腾讯面试) 这里我们以某大型企业数万名员工年龄排序来进行一个…

RV1126笔记十四:吸烟行为检测及部署<二>

若该文为原创文章,转载请注明原文出处。 PC下yolov5环境搭建 我使用的训练环境是Windows10+MiniConda 接下来记录搭建全过程 备注:条件允许就使用ubuntu物理机,最好要有显卡,训练有显卡速度会快很多,没有显卡,训练300轮,亲测大概40小时,不值得。 一、miniconda 安装…