ARM32平台系统crash(系统崩溃) 问题定位的一种解决方法

news2024/12/29 10:47:04

说明

分享一种crash问题定位的一种解决方法,仅供参考。  

ARM32平台上通过错误使用内存,触发系统异常,系统崩溃。系统异常被挂起后,能在串口中看到异常调用栈打印信息和关键寄存器信息。

如下所示,excType表示异常类型,值为4表示数据终止异常,其它数值可以查看芯片手册。

通过这些信息可以基本定位到异常所在函数和其调用栈的关系,为分析系统死机崩溃提供分析,便于查找问题所在。

crash日志

[11:31:32.475]收←◆--- device idle,timeout=10000,lastT=77601,curT=87612
orbSendcmd: | F5 AE 02 FE 04 00 33 00 00 00 26 FD |
data_abort fault fsr:0x29, far:0x00000001
Abort caused by a read instruction. Domain fault, section
excType = 0x4
taskName = DeviceStaThd
taskID = 29
task stackSize = 24576
system mem addr = 0x40aaecc0
excBuffAddr pc = 0x4004cf34
excBuffAddr lr = 0x400522dc
excBuffAddr sp = 0x400f8340
excBuffAddr fp = 0x41300354
R0         = 0x1
R1         = 0x0
R2         = 0x7fffffff
R3         = 0xffffffff
R4         = 0x7fffffff
R5         = 0x1
R6         = 0x0
R7         = 0x0
R8         = 0x0
R9         = 0x1
R10        = 0x0
R11        = 0x41300354
R12        = 0xffffffff
CPSR       = 0x20000013
*******backtrace begin*******
traceback 0 -- lr = 0x 400537ec    fp = 0x4130065c
traceback 1 -- lr = 0x40054a74    fp = 0x4130075c
traceback 2 -- lr = 0x40055ab8    fp = 0x41300824
traceback 3 -- lr = 0x40471a8c    fp = 0x41300c9c
traceback 4 -- lr = 0x40145f54    fp = 0x41300d24
traceback 5 -- lr = 0x40146384    fp = 0x41300db4
traceback 6 -- lr = 0x40146930    fp = 0x41300dc4
traceback 7 -- lr = 0x40046c58    fp = 0x41300dd4
traceback 8 -- lr = 0x4005044c    fp = 0xb0b0b0b

利用反汇编文件.asm

打开编译后生成的 asm 反汇编文件

搜索PC指针 0x4004cf34 在asm文件中的位置(去掉0x)

PC地址指向发生异常时程序正在执行的指令。在当前执行的二进制文件对应的asm文件中,查找PC值 4004cf34,找到当前CPU正在执行的指令行,得到如下所示结果。

4004cf20 <memchr>:
4004cf20:	e3100003 	tst	r0, #3
4004cf24:	e6ef1071 	uxtb	r1, r1
4004cf28:	0a000010 	beq	4004cf70 <memchr+0x50>
4004cf2c:	e3520000 	cmp	r2, #0
4004cf30:	0a000035 	beq	4004d00c <memchr+0xec>

4004cf34:	e5d03000 	ldrb	r3, [r0]

4004cf38:	e1530001 	cmp	r3, r1
4004cf3c:	0a000042 	beq	4004d04c <memchr+0x12c>
4004cf40:	e2803001 	add	r3, r0, #1
4004cf44:	ea000004 	b	4004cf5c <memchr+0x3c>
4004cf48:	e3520000 	cmp	r2, #0
4004cf4c:	0a00002e 	beq	4004d00c <memchr+0xec>

ldrb指令作用:LDRB指令用于从内存中将一个8位的字节数据读取到指令中的目标寄存器中。并将寄存器的高24位清零。

LDRB R0, [R2,#3]    ;将内存单元(R2+3)中字节数据读取到R0中,R0中高24位设置成0

LDRB R0,[R1]    ;将内存单元(R1)中的字节数据读取到R0中,R0中高24位设置成0

结合指令分析:寄存器r0读到r3,r0为0x1,r3为0xffffffff,r3超出内存范围

cpu执行该命令发生了数据终止异常。可以确认,memchr 被调用拷贝时可能因为长度问题导致异常

根据 LR链接寄存器值 查找调用栈

从异常信息的backtrace begin开始,打印的是调用栈信息。在asm文件中查找backtrace 0 400537ec 对应的LR,如下所示。

400537e4:	e1a00009 	mov	r0, r9
400537e8:	ebfffab4 	bl	400522c0 <strnlen>

400537ec:	e7d93000 	ldrb	r3, [r9, r0]

400537f0:	e0896000 	add	r6, r9, r0
400537f4:	e3530000 	cmp	r3, #0
400537f8:	0affff12 	beq	40053448 <printf_core+0xb48>
400537fc:	eafffe12 	b	4005304c <printf_core+0x74c>
40053800:	e3170b02 	tst	r7, #2048	; 0x800
40053804:	1a000255 	bne	40054160 <printf_core+0x1860>
40053808:	e51f3c90 	ldr	r3, [pc, #-3216]	; 40052b80 <printf_core+0x280>
4005380c:	e2072001 	and	r2, r7, #1
40053810:	e51b12e0 	ldr	r1, [fp, #-736]	; 0xfffffd20
40053814:	e3520000 	cmp	r2, #0
40053818:	e2832005 	add	r2, r3, #5
4005381c:	13a01001 	movne	r1, #1
40053820:	e50b12e0 	str	r1, [fp, #-736]	; 0xfffffd20
40053824:	11a03002 	movne	r3, r2
40053828:	e50b32e4 	str	r3, [fp, #-740]	; 0xfffffd1c

可见,是 strnlen 调用了 memchr。

我们从strnlen中的实现也可以确定此论证

使用backtrace begin和源码排查

但是此信息还不足以确定问题,我们可以继续从backtrace begin提供的内存地址开始找

从backtrace1中我们确定为printf_core接口导致

traceback 1 -- lr = 40054a74    fp = 0x4130075c
40054a70:	ebfff7a2 	bl	40052900 <printf_core>
40054a74:	e1a05000 	mov	r5, r0
40054a78:	e3580000 	cmp	r8, #0
40054a7c:	0a00000d 	beq	40054ab8 <vfprintf+0x110>
40054a80:	e5943024 	ldr	r3, [r4, #36]	; 0x24

通过与代码结合,底层接口实现查找,确实如图所示

继续根据traceback 2 -- lr = 40055ab8    fp = 0x41300824找到printf_core为vprintf调用

traceback 2 -- lr = 40055ab8    fp = 0x41300824
40055ab4:	ebfffbbb 	bl	400549a8 <vfprintf>
40055ab8:	e1a05000 	mov	r5, r0
40055abc:	e30a337c 	movw	r3, #41852	; 0xa37c
40055ac0:	e1a00005 	mov	r0, r5
40055ac4:	e3443001 	movt	r3, #16385	; 0x4001
40055ac8:	e5932000 	ldr	r2, [r3]
40055acc:	e51b3020 	ldr	r3, [fp, #-32]	; 0xffffffe0
40055ad0:	e0332002 	eors	r2, r3, r2
40055ad4:	1a00001a 	bne	40055b44 <vsnprintf+0x118>

根据底层代码实现也可验证无问题

继续往上查找,基本可以确定是打印接口导致

traceback 3 -- lr = 40471a8c    fp = 0x41300c9c
40471a88:	ebef8fe7 	bl	40055a2c <vsnprintf>
40471a8c:	e1a00005 	mov	r0, r5
40471a90:	ebef81b7 	bl	40052174 <strlen>
40471a94:	e2402001 	sub	r2, r0, #1
40471a98:	e7d53002 	ldrb	r3, [r5, r2]
40471a9c:	e353000a 	cmp	r3, #10
40471aa0:	0a000008 	beq	40471ac8 <orbbec_log_print+0xe8>

继续往上查找我们是通过哪个方法的打印接口导致的crash

traceback 4 -- lr = 40145f54    fp = 0x41300d24
40145f50:	eb0caea2 	bl	404719e0 <orbbec_log_print>
40145f54:	e3e00000 	mvn	r0, #0
40145f58:	eaffffe3 	b	40145eec <_ZN17CDeviceStaManager25DeviceHealthStatusMonitorEPc+0x2d4>

traceback 5 -- lr = 40146384    fp = 0x41300db4
40146380:	ebfffe24 	bl	40145c18 <_ZN17CDeviceStaManager25DeviceHealthStatusMonitorEPc>
40146384:	e51b3048 	ldr	r3, [fp, #-72]	; 0xffffffb8
40146388:	e1530006 	cmp	r3, r6
4014638c:	1affffa8 	bne	40146234 <_ZN17CDeviceStaManager13DeviceStaProcEv+0x1a0>

traceback 6 -- lr = 40146930    fp = 0x41300dc4
40146904 <_ZN17CDeviceStaManager12DeviceStaThdEPv>:
40146904:	e30e1464 	movw	r1, #58468	; 0xe464
40146908:	e92d4830 	push	{r4, r5, fp, lr}
4014690c:	e1a04000 	mov	r4, r0
40146910:	e3441076 	movt	r1, #16502	; 0x4076
40146914:	e28db00c 	add	fp, sp, #12
40146918:	e3a0000f 	mov	r0, #15
4014691c:	ebfdc7d0 	bl	400b8864 <prctl>
40146920:	e3540000 	cmp	r4, #0
40146924:	0a000001 	beq	40146930 <_ZN17CDeviceStaManager12DeviceStaThdEPv+0x2c>
40146928:	e1a00004 	mov	r0, r4
4014692c:	ebfffdd8 	bl	40146094 <_ZN17CDeviceStaManager13DeviceStaProcEv>
40146930:	e3a00000 	mov	r0, #0
40146934:	e8bd8830 	pop	{r4, r5, fp, pc}

再根据死机前对信息最后打印可以确定问题所在了,发送完此命令后的一条打印导致的问题

[11:31:31.083]收←◆31 08:01:26.221 [wifi] wifi status check = not connect, retry = 86

[11:31:32.082]收←◆31 08:01:27.221 [wifi] wifi status check = not connect, retry = 87

[11:31:32.475]收←◆--- device idle,timeout=10000,lastT=77601,curT=87612
orbSendcmd: | F5 AE 02 FE 04 00 33 00 00 00 26 FD |
data_abort fault fsr:0x29, far:0x00000001
Abort caused by a read instruction. Domain fault, section

所以到这里,问题可以确定为

DeviceStaThd()->DeviceStaProc()->DeviceHealthStatusMonitor()
->printf("orbSendcmd")->后一条printf导致的crash

总结

1. LR

LR用途有二,一是保存子程序返回地址,当调用BL、BX、BLX等跳转指令时会自动保存返回地址到LR;二是保存异常发生的异常返回地址

2. PC

PC(Program Counter)为程序计数器,用于保存程序的执行地址,在ARM的三级流水线架构中,程序流水线包括取址、译码和执行三个阶段,PC指向的是当前取址的程序地址,所以32位ARM中,译码地址(正在解析还未执行的程序)为PC-4,执行地址(当前正在执行的程序地址)为PC-8。
当突然发生中断的时候,保存的是PC的地址。如果返回的时候返回PC,那么中间就有一个指令没有执行,所以用SUB pc lr-irq #4。

3. SP

每一种异常模式都有其自己独立的r13,它通常指向异常模式所专用的堆栈,也就是说五种异常模式、非异常模式(用户模式和系统模式),都有各自独立的堆栈,用不同的堆栈指针来索引。这样当ARM进入异常模式的时候,程序就可以把一般通用寄存器压入堆栈,返回时再出栈,保证了各种模式下程序的状态的完整性。

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

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

相关文章

上传文件前后端处理【vue3 + springboot】

前端 1.处理modal框 <template><n-modalv-model:show"modalVisible"preset"card":title"title"class"w-700px"><n-space class"w-full pt-16px" :size"24" justify"end"><n-but…

python数据分析:采集分析岗位数据,看看薪资的高低都受什么因素影响呢

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 又到了学Python时刻~ 在我们学习的时候,通常会产生疑问:这个行业前景好不好呢? 今天我们就用python的数据分析这个就业方向来举例 看一下都有哪些因素影响了薪资的高低呢&#xff1f; 数据采集 模块使用: reques…

这些js原型及原型链面试题你能做对几道

一、前言 在面试过程中&#xff0c;频频被原型相关知识问住&#xff0c;每次回答都支支吾吾。后来有家非常心仪的公司&#xff0c;在二面时&#xff0c;果不其然&#xff0c;又问原型了&#xff01; 我痛下决心用了两天时间钻研了下原型&#xff0c;弄明白后发现世界都明亮了…

Spark 在 KaiwuDB 中的应用与实践

线上沙龙-技术流第 24 期营业啦01月12日&#xff08;周四&#xff09;19:30开务数据库 - B站直播间当数据库面对大量数据复杂 OLAP 查询时&#xff0c;性能出现局限性&#xff0c;无法满足用户 AP 方面的高性能要求。为此&#xff0c;KaiwuDB 推出了此项解决方案&#xff1a;借…

【NI Multisim 14.0原理图环境设置——电路图属性设置】

目录 序言 一、电路图属性设置 &#x1f34a;1.设置对象可见性 &#x1f34a;2.设置图纸颜色 &#x1f34a;3.设置图纸尺寸 &#x1f34a;4.设置图纸方向 &#x1f34a;5.设置图纸单位 &#x1f34a;6.设置图纸网格点 &#x1f34a;7.设置图纸边框 &#x1f34a;8. 设…

ELK安装使用

太久没用了&#xff0c;熟悉一下。 JDK1.8以上环境 下载地址 elasticsearch&#xff1a;https://www.elastic.co/cn/downloads/elasticsearch kibana: https://www.elastic.co/cn/downloads/kibana logstash &#xff1a; https://www.elastic.co/cn/downloads/logstash…

社招前端二面必会手写面试题总结

字符串查找 请使用最基本的遍历来实现判断字符串 a 是否被包含在字符串 b 中&#xff0c;并返回第一次出现的位置&#xff08;找不到返回 -1&#xff09;。 a34;b1234567; // 返回 2 a35;b1234567; // 返回 -1 a355;b12354355; // 返回 5 isContain(a,b);function isContain(a,…

RS—|下载Landsat8/9数据并进行ENVI大气校正(FLAASH模型)

文章目录1、 数据的下载。2、 辐射定标3、大气校正1、 数据的下载。 下载网址&#xff1a;链接: GloVis (usgs.gov)。下载的数据为2022年8月1日湖南省北部的遥感影像数据。该数据为L1级产品&#xff0c;只经过了几何校正&#xff0c;没有经过辐射定标和大气校正。 图1-1.下载…

富而喜悦2023直播盛典 唐苓馨主题演说“特别的礼物”!

网讯2023年1月1日19:30&#xff0c;富而喜悦一年一渡“特别的礼物”新年主题直播盛典晚会如约而至。富而喜悦品牌创始人唐苓馨女士&#xff0c;用自己与身边人的真实故事&#xff0c;为您讲述了“遇见生活中特别的礼物”。以下是富而喜悦品牌创始人唐苓馨女士在2023富而喜悦一年…

手写RPC框架05-通过SPI机制增加框架的扩展性的设计与实现

源码地址&#xff1a;https://github.com/lhj502819/IRpc/tree/v6 系列文章&#xff1a; 注册中心模块实现路由模块实现序列化模块实现过滤器模块实现自定义SPI机制增加框架的扩展性的设计与实现 现有的问题 在上一章节末尾我们提到了&#xff0c;目前我们的RPC框架可扩展性…

发表计算机SCI论文需要注意什么? - 易智编译EaseEditing

一篇SCI&#xff0c;除了能让审稿人浅显易懂的了解你的表达之外&#xff0c;我们还需要在内容上做好&#xff1a; 1、SCI论文标题创新、简洁 创新是因为写科技文章的目的在于报道新的科技进展&#xff0c;缺乏创新因素就会失去发表的意义。 但运用创新要建立在已有的科研成果…

QT部件透明阴影效果与不规则窗体

透明效果原始效果设置整个窗体透明&#xff0c;调用setWindowOpacity( )方法&#xff0c;传入一个0~1之间的值来表示透明度&#xff1b;1表示不透明&#xff0c;0表示完全透明setWindowOpacity(0.5);//0~1之间设置窗体透明&#xff0c;部件不透明setWindowFlags(Qt::FramelessW…

MATLAB | 赠书 | 如何从热图中提取数据

gzh上这篇文章正在抽奖赠书&#xff1a;截止日期2023年1月9日12&#xff1a;00&#xff08;周一&#xff09; MATLAB | 文末赠书 | 如何从热图中提取数据 赠送3本由北京大小出版社提供的《SPSS统计分析大全》 这期做了个可能有用的小工具&#xff0c;一般论文中热图很少给出…

十.指针进阶(对指针的深度理解)

目录 一. 字符指针 1.字符指针的定义 2.字符指针的用法 3.字符指针练习 二. 数组指针 1.指针数组的定义 2.指针数组的用法 三. 指针数组 1.数组指针的定义 2.数组名和&数组名的区别 3.数组指针的用法 4.练习 四. 数组传参和指针传参 1.一维数组传参 2.二维数…

十、MyBatisX插件

文章目录十、MyBatisX插件1 安装MyBatisX插件2 MybatisX代码速成3 在mapper接口中实现自定义功能【尚硅谷】MyBatisPlus教程-讲师&#xff1a;杨博超 失败&#xff0c;是正因你在距成功一步之遥的时候停住了脚步。 十、MyBatisX插件 MyBatis-Plus为我们提供了强大的mapper和ser…

Jdbc配置文件连接mysql8.0——通过拼接字符串进行批量增删改操作

目录 一、基类BaseDao 二、对dog表的批量增删改操作 (一)Dog类 (二)DogDao接口 (三)DogDaoImpl实现类 1.批量新增 2.批量删除 3.批量修改 (四)Test测试 1.新增 2.删除 3.修改 三、对master表进行批量增删改 (一)Master类 (二)MasterDao接口 (三)MasterDaoImpl实…

RK3588平台开发系列讲解(内核调试篇)oops分析

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、oops简介二、oops分析2.1、实验代码2.2、oops信息2.3、oops分析沉淀、分享、成长,让自己和他人都能有所收获!😄 📢当系统内核发生kernel panic的时候,系统会打印出oops信息,本篇主要介绍如何根据oops定位问…

2022/1/6总结

今天学习了KMP算法。 KMP算法 这是一个字符串查找的算法&#xff0c;我们之前学习的字符串查找都是暴力穷举&#xff0c;然而这个效率太低&#xff0c;于是有三位大佬发明了线性的KMP算法。 算法说难不难&#xff0c;说简单也不简单。 算法的核心思想是找到最长的相等的前…

Struts2框架之Action配置

Struts2框架之Action配置Action配置1、访问Action的三种方式1.1、method属性访问1.2、Action动态方法调用1.3、通配符调用2、配置默认的ActionAction配置 Action控制器在Struts2框架中至关重要&#xff0c;主要作用如下&#xff1a; 封装工作单元数据转移的场所返回结果字符串…

(黑马C++)L07 多态

一、多态的基本概念 多态是面向对象程序设计语言中除数据抽象和继承之外的第三个基本特征。 多态&#xff1a;父类的引用或者指针指向子类对象 C支持编译时多态&#xff08;静态多态&#xff09;和运行时多态&#xff08;动态多态&#xff09;&#xff0c;运算符重载和函数重…