Android问题笔记四十三:JNI 开发如何快速定位崩溃问题

  • 点击跳转=>Unity3D特效百例
  • 点击跳转=>案例项目实战源码
  • 点击跳转=>游戏脚本-辅助自动化
  • 点击跳转=>Android控件全解手册
  • 点击跳转=>Scratch编程案例
  • 点击跳转=>软考全系列

👉关于作者

专注于Android/Unity和各种游戏开发技巧,以及各种资源分享(网站、工具、素材、源码、游戏等)
有什么需要欢迎底部卡片私我,交流让学习不再孤单

在这里插入图片描述

👉实践过程

😜问题

我们做 JNI 开发的时候,一旦触发 BUG 可能直接造成崩溃,当 Linux 应用程序在执行时如果发生严重错误,一般会导致程序 crash。Linux 专门提供了一类 crash 信号,在程序接收到此类信号时,缺省操作是将 crash 的现场信息及时记录到 core 文件,接着进行终止进程的操作。
而且崩溃不能在 Android Studio 的 Logcat 中直接查看出来。这就给定位问题产生了很大的阻碍。但这并不是无法定位。

😜解决

tombstones介绍

当 JNI 运行时候,系统就会注册一些信息连接到 debuggerd 的 signal handlers,这时候如果系统触发了 crash ,就会在/data/tombstones下生成一个 tombstone ,她就像墓碑一样记录了死亡了的进程的基本信息(例如进程的进程号,线程号),死亡的地址(在哪个地址上发生了 Crash),死亡时的现场是什么样的(记录了一系列的堆栈调用信息)等等。

console:/ # cat /data/tombstones/tombstone_00                                  
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'Allwinner/petrel_p1/petrel-p1:9/PPR1.181005.003/20210826-112106:eng/test-keys'
Revision: '0'
ABI: 'arm'
pid: 1893, tid: 2906, name: bonjour  >>> /system/bin/ndktest <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xacc03064
    r0  000003ff  r1  acc0311c  r2  00000004  r3  f3cec54f
    r4  acbcb640  r5  000000b8  r6  000007c0  r7  ef57f3f8
    r8  acbcc8b4  r9  acbd53fc  r10 00000400  r11 acbc83d8
    ip  f3d32638  sp  ef57f3b0  lr  acb47c5f  pc  acb47c6a

backtrace:
    #00 pc 000a8c6a  /system/bin/ndktest
    #01 pc 000532e5  /system/bin/ndktest
    #02 pc 00063a25  /system/lib/libc.so (__pthread_start(void*)+22)
    #03 pc 0001df95  /system/lib/libc.so (__start_thread+22)

stack:
         ef57f370  00000000
         ef57f374  00000000
         ef57f378  00000000
         ef57f37c  00010000
         ef57f380  612709a0

大概就像上面那样。里面记录了产生问题的进程id(如上面的pid),也记录了崩溃的原因(如上面的signal 11…),同样也记录了更重要的信息——崩溃的地址(上面的backtrace)。
可即使到这了,我们还是无法直接看出错误在哪一行啊。
不要急,上面只是告诉我们日志在什么地方,通常我们是不会手动去查看日志的。我们借住工具可以直接输出出来错误行。

利用addr2line

addr2line 是 NDK 中的工具,我们需要他捕捉错误信息,然后进行地址转换,就能看见我们出错误的代码行数。
该工具在你的 sdk 文件夹下,如下面是我的 sdk 安装地址以及 NDK 版本号:

H:\studio\sdk\ndk\21.4.7075529\toolchains\aarch64-linux-android-4.9\prebuilt\windows-x86_64\bin

在这里插入图片描述
这时候需要命令行工具,有三种形式:

  1. 直接在这个路径下,shift+右键 打开 Powershell
    在这里插入图片描述
  2. 利用传统的 cmd 工具。
  3. 如果在安装 Adnroid Studio的时候配置好了环境变量,也可以在Studio的Terminal中进行操作。

我是利用的方式一。

我们继续操作:

  1. 用数据线将 Studio 和 设备进行连接,然后触发崩溃

  2. 在 Logcat 中查看错误信息。记住这些内存地址在这里插入图片描述

  3. 找到你的项目这个 SO 文件的完整路径。集成这个 SO 的项目 或者 你用来编写 SO 的项目都可以。我是使用编写 SO 的项目详细地址

  4. 在命名行中敲如下代码:在这里插入图片描述
    红线表示 addr2line 工具的完整路径,绿线表示 so 的路径,黄线表示第二步中你记路的地址,空格可以输入多个。
    其中-C -f :表示打印错误行数所在的函数名称,-e:表示打印错误地址的对应路径及行数

然后回车。就能看到具体的错误行数了。
在这里插入图片描述
然后再具体问题具体分析。

😜注意

这里 在用add2line工具时,不要用.\libs\armeabi-v7a\ndktest,而是要用.\obj\local\armeabi-v7a\下的ndktest,因为libs下的文件已经去掉了调试信息,你可以对比下,libs下的ndktest比obj下的要小的多。
除此之外,如果嫌麻烦,我们还可以封装一个 Bat 工具。

@echo off
rem current direction
set cur_dir=%cd%
 
rem addr2line tool path
set add2line_path=E:\android-ndk-r16b-windows-x86_64\android-ndk-r16b\toolchains\aarch64-linux-android-4.9\prebuilt\windows-x86_64\bin\aarch64-linux-android-addr2line.exe
 
rem debug file
set /p debug_file=请输入当前目录下debug文件名:
 
rem debug_file_path
set debug_file_path=%cur_dir%\%debug_file%
 
rem debug address
set /p debug_addr=请输入异常时PC寄存器值:
 
echo ----------------------- addr2line ------------------------
echo debug文件路径: %debug_file_path%  PC=%debug_addr%
 
if exist %debug_file_path% (
%add2line_path% -e %debug_file_path% -f %debug_addr% 
) else (
echo debug file is no exist. 
)
 
echo ---------------------------------------------------------
pause

上面代码的set add2line_path=后面跟的就是那个addr2line工具路径。
然后将这个 bat 文件和 so 文件放置相同的文件夹下。触发下崩溃。
双击此脚本,然后输入库名和寄存器地址,然后就可以查到出错的行号了。

上面演示的是最最最幸运的效果,但实际中,第三方的so库一般都是不提供源码,又或者已加密了,所以此时得出的是行号为??:?或??:0

如果遇到 addr2line 得到??:?或??:0的情况,原因就是编译得到的so文件没有附加上符号表(symbolic)信息。

  • 如果是同事或者自己开发的直接使用 debug 模式
  • 如果是大厂出的SO,一般不会出现问题
  • 如果是合作方的,就需要和他们联合开发调试了。这个方式是最麻烦的

👉其他

📢作者:小空和小芝中的小空
📢转载说明-务必注明来源:https://zhima.blog.csdn.net/
📢这位道友请留步☁️,我观你气度不凡,谈吐间隐隐有王者霸气💚,日后定有一番大作为📝!!!旁边有点赞👍收藏🌟今日传你,点了吧,未来你成功☀️,我分文不取,若不成功⚡️,也好回来找我。

温馨提示点击下方卡片获取更多意想不到的资源。
空名先生

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【c++|opencv】二、灰度变换和空间滤波---2.直方图和均衡化

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 图像直方图、直方图均衡化 1. 图像直方图 #include <iostream> #include <opencv2/opencv.hpp>using namespace cv; using namespace std;…

Django之登录注册

最近在准备上线一个网站&#xff08;基于django的编程技术学习与外包服务网站&#xff09;&#xff0c;所以会将自己的在做这个项目的过程中遇到的模块业务以及所涉及到的部分技术记录在CSDN平台里&#xff0c;一是希望可以帮到有需要的同学&#xff0c;二十以供自己后续回顾学…

玩转ChatGPT:批量下载Alphafold的蛋白pdb文件

一、写在前面 突发奇想&#xff0c;想批量下载Alphafold网站的蛋白pdb文件&#xff0c;后续再做个分子对接用。又不想手动下载&#xff0c;来求助CSDN和GPT。 二、CSDN白嫖基础代码 CSDN大神多&#xff0c;这不&#xff0c;找到一个&#xff1a;Alphafold批量下载蛋白的pdb文…

Flutter PopupMenuButton下拉菜单

下拉菜单是移动应用交互中一种常见的交互方式,可以使用下拉列表来展示多个内容标签,实现页面引导的作用。在Flutter开发中,实现下拉弹框主要有两种方式,一种是继承Dialog组件使用自定义布局的方式实现,另一种则是使用官方的PopupMenuButton组件进行实现。 如果没有特殊的…

分享一下怎么做一个商城小程序

如何制作一个商城小程序&#xff1a;功能解析、设计思路与实现方法 一、引言 随着移动设备的普及和微信小程序的兴起&#xff0c;越来越多的消费者选择在商城小程序上进行购物。商城小程序具有便捷、高效、即用即走等特点&#xff0c;为企业提供了新的销售渠道和推广方式。本…

吴恩达《机器学习》2-5->2-7:梯度下降算法与理解

一、梯度下降算法 梯度下降算法的目标是通过反复迭代来更新模型参数&#xff0c;以便最小化代价函数。代价函数通常用于衡量模型的性能&#xff0c;我们希望找到使代价函数最小的参数值。这个过程通常分为以下几个步骤&#xff1a; 初始化参数&#xff1a; 随机或设定初始参数…

C++STL----list的模拟实现

文章目录 list模拟实现的大致框架节点类的模拟实现迭代器类的模拟实现迭代器类存在的意义迭代器类的模板参数说明运算符的重载--运算符的重载&#xff01;与运算符的重载*运算符的重载->运算符的重载 list的模拟实现默认成员函数迭代器相关函数元素修改相关函数front和backi…

edge浏览器的隐藏功能

1. edge://version 查看版本信息 2. edge://flags 特性界面 具体到某一特性&#xff1a;edge://flags/#overlay-scrollbars 3. edge://settings设置界面 详情可参考chrome: 4. edge://extensions 扩展程序页面 5. edge://net-internals 网络事件信息 6. edge://component…

【指针、数组参数】

void interchange(int * u,int * v) {int temp *u; //带*号指向该地址上的值*u *v;*v temp; }int main1(void) {int x 10;int y 5;printf("before: x %d y %d\n",x,y);interchange(&x,&y);printf("after: x %d y %d\n",x,y); }结果&…

Redis测试新手入门教程

在测试过程中&#xff0c;我们或多或少会接触到Redis&#xff0c;今天就把在小破站看到的三丰老师课程&#xff0c;把笔记整理了下&#xff0c;用来备忘&#xff0c;也希望能给大家带来亿点点收获。 主要分为两个部分&#xff1a; 一、缓存技术在后端架构中是如何应用的&#…

十八、模型构建器(ModelBuilder)快速提取城市建成区——批量掩膜提取夜光数据、夜光数据转面、面数据融合、要素转Excel(基于参考比较法)

一、前言 前文实现批量投影栅格、转为整型,接下来重点实现批量提取夜光数据,夜光数据转面、夜光数据面数据融合、要素转Excel。将相关结果转为Excel,接下来就是在Excel中进行阈值的确定,阈值确定无法通过批量操作,除非采用其他方式,但是那样的学习成本较高,对于参考比较…

Linux Centos7安装后,无法查询到IP地址,无ens0,只有lo和ens33的解决方案

文章目录 前言1 查看network-scripts目录2 创建并配置 ifcfg-ens33 文件3 禁用NetworkManager4 重新启动网络服务总结 前言 在VMware中&#xff0c;安装Linux centos7操作系统后&#xff0c;想查询本机的IP地址&#xff0c;执行ifconfig命令 ifconfig结果如下&#xff1a; 结…

基于深度学习的单图像人群计数研究:网络设计、损失函数和监控信号

摘要 https://arxiv.org/pdf/2012.15685v2.pdf 单图像人群计数是一个具有挑战性的计算机视觉问题,在公共安全、城市规划、交通管理等领域有着广泛的应用。近年来,随着深度学习技术的发展,人群计数引起了广泛的关注并取得了巨大的成功。通过系统地回顾和总结2015年以来基于深…

【Overload游戏引擎细节分析】PBR材质Shader---完结篇

PBR基于物理的渲染可以实现更加真实的效果&#xff0c;其Shader值得分析一下。但PBR需要较多的基础知识&#xff0c;不适合不会OpenGL的朋友。 一、PBR理论 PBR指基于物理的渲染&#xff0c;其理论较多&#xff0c;需要的基础知识也较多&#xff0c;我在这就不再写一遍了&…

【Vue】vant上传封装方法,van-uploader上传接口封装

项目场景&#xff1a; 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; 在移动端项目中&#xff0c;使用vant组件上传&#xff0c;但是vant没有上传方法&#xff0c;需要自己写。 html代码 <van-uploader v-model"fileList" :max-size"50…

SV-10A-4G IP网络报警非可视终端 (4G版)

SV-10A-4G IP网络报警非可视终端 &#xff08;4G版&#xff09; https://item.taobao.com/item.htm?spma21dvs.23580594.0.0.621e3d0dpv5knb&ftt&id745728046948 产品简介&#xff1a; 通过局域网/广域网网组网的网络报警系统&#xff0c;改变传统局域网组网…

[Linux C] signal 的使用

前言&#xff1a; signal 是一种通信机制&#xff0c;可以跨进程发送&#xff0c;可以同进程跨线程发送&#xff0c;可以不同进程向指定线程发送。 信号的创建有两套api&#xff0c;一个是signal&#xff0c;一个是sigaction&#xff0c;signal缺陷很多&#xff0c;比如没有提…

【脚本笔记】AssetDatabase

AssetDatabase是编辑器下的处理资源操作的重要类&#xff0c;主要用于访问资源并针对资源执行操作的接口。 这里面所有的操作路径都是基于Unity项目的相对路径也就是Assets/xxx或者Assets/xxx.jpg这种。CacheServer 主要解决的是缩短大型团队导入资源的时间。当配置后&#xff…

论文阅读——InstructGPT

论文&#xff1a;Training_language_models_to_follow_instructions_with_human_feedback.pdf (openai.com) github&#xff1a;GitHub - openai/following-instructions-human-feedback 将语言模型做得更大并不能从本质上使它们更好地遵循用户的意图。例如&#xff0c;大型语…