今天有人在家里做客吃饭,买了一瓶大瓶的可乐,有2.5L,喝了一半还剩下一半没有喝完,今天是喝不下了,扔了很可惜,不知道放到明天还可以喝吗。隔夜的可乐能喝吗?隔夜......
2023-04-30 1172
我们在做Linux开发时,常常会遇到程序崩溃的问题,这时会用gdb或者通过查看反汇编的方式去对程序进行分析,接下来,我们从底层的角度,去讲述如何分析程序崩溃的原因。
一、常见BUG在进行分析前,先看看我总结归纳的常见BUG:
1.内存错误:内存错误往往出现在使用了未分配的内存,或者没有及时释放分配的内存。
2.指针错误:指针错误往往出现在使用了空指针,或者是指向的地址在函数返回后丢失,或者是偏移量出了问题,这个话题暂时不展开讨论。
3.判断条件出错:比如 if (a == 1) 写成了 if (a=1),if (a && b) 写成了 if (a & b)。
4.参数未初始化比较典型的就是申请结构体变量没对其进行memset,加之接口内部没做参数判断,从而传参导致接口异常。
5.未考虑字节序在跨平台通信时要考虑字节序的问题,arm一般是小端字节序( little - endian ),x86一般是大端字节序( big - endian)。arm和x86进行通信时,要考虑到字节序问题。
6.线程同步错误往往体现在共享数据上锁不当,导致线程死锁。
7.字节对齐错误需要了解编译器对于字节对齐的默认属性,一般是4字节对齐,体现在结构体的设计方面。如果字节对齐做的不好,软件版本更新迭代会带来极大的隐患,通常做法是加上reserve字段。
8.配对操作没调用完全比如open没有及时close,init没有及时release,从而导致资源的浪费。
二、从汇编角度分析C程序我们在嵌入式开发中,使用arm架构居多,所以这里讨论的是arm架构的分析方案,如果用x86也可以用类似的思想。我们日常开发中遇到的程序崩溃,比较难查的问题往往是出现在内存访问部分,下面我们通过底层的汇编程序来讲述一段C语言程序,对于内存,硬件,是怎样一个执行流程。
1.arm汇编相关理论基础下面我列举一些arm汇编的寄存器,并对其进行描述 常用的arm用户态寄存器如上表所示,有r0~r15这16个寄存器 r0~r3:通常在函数传参时使用(从左到右的顺序,大于4个参数时使用栈来传递)和返回值(r0通常被用作返回值)。在函数内部 r0-r3 也可以用来存储局部变量。 r4~r8,r10,r11:通常用来保存局部变量。r11通常用来作为(FP)栈基地址(下面会对这些概念进行讲述) r12:可能在函数调用时被链接器使用,在函数内部,也可以存储局部变量。 r13:是SP寄存器,就是当前函数的栈顶指针。 r14:是LR寄存器,存放当前函数的返回地址。 r15:是PC寄存器,存放当前指令的地址。
上面讲述的FP,SP,LR,PC寄存器,它寄存器里面的内容是地址,这点不要混淆。
2.内存中的栈帧结构刚刚我们提到了FP,SP,LR,PC寄存器,现在我们来展开聊聊这几个寄存器。
PC指针:刚刚提到PC指针里面存放着当前指令的地址,因为在我们arm架构,传统上是五级流水线,简单描述就是取址,然后取完代码是二进制,对它进行译码,翻译成各个动作,然后cpu参与计算,最后返回。PC指针就存放着当前指令的地址,扮演的角色就是告诉cpu需要访问的地址,也对应五级流水线中的取址操作。
SP指针:在函数申请变量的时候,会有一个动态压栈的过程,栈的大小会随着变量申请而逐渐增长,SP指针就指向你动态压栈所处在的地址。
FP指针:当前函数的起始地址。在函数调用时,进入另一个函数接口,也会进入另一个栈帧结构,里面会保存调用者的的起始地址(FP),用于出现问题时回溯,同时也有当前函数的起始地址(FP)。
LR指针:函数调用时,调用者的下一条指令地址。用于函数调用完返回时,可以进入下一条指令。
我们不妨先看看内存中的栈帧结构。 这就是内存中的栈帧结构,上图就是main函数在调用func1时的栈帧结构。绿色的是处在func1函数里面的,灰色的是在main函数里面的。 通过这张图,我们可以看出,在发生函数调用时,FP寄存器会指向当前函数调用的起始地址。在func1内部(绿色部分)还有一个FP,这个FP不是FP寄存器,而是内存中的数据,也表示地址。它指向调用者(main)的起始地址。它主要是在程序崩溃时,用来回溯上一级的PC LR SP FP的值,所以在调用时会保存上一个栈帧的数据,用来崩溃的时候一层一层回溯回去。
3.举例说明在举例说明例子之前,先讲一下几个常用的汇编指令
mov:给某个寄存器赋值mov r3, #8add:加法运算add r3, r3, #4sub:减法运算sub r3, r3, #4str:把寄存器的值写入内存 str r3, [fp, #-8] ldr:从内存中取数据到寄存器ldr r0, [pc, #20]bl:跳转到指定地址bl 83ec下面我来写一段很简单的代码
#include int func(int num1, int num2, int num3){ int n = 0; n = num1 + num2; n = n + num3; return n;}int main(){ int a = 0; int b = 1; a = func(1, 2, b); printf("value = %dn", a); return 0;}翻译成反汇编(这里采用海思的交叉编译工具编译,然后通过objdump生成反汇编)
arm-himix200-linux-gcc test.c -o testarm-himix200-linux-objdump -d test > debug.txt反汇编中的C语言部分
00010410 : 10410: e52db004 push {fp} ; (str fp, [sp, #-4]!) 10414: e28db000 add fp, sp, #0 10418: e24dd01c sub sp, sp, #28 1041c: e50b0010 str r0, [fp, #-16] 10420: e50b1014 str r1, [fp, #-20] ; 0xffffffec 10424: e50b2018 str r2, [fp, #-24] ; 0xffffffe8 10428: e3a03000 mov r3, #0 1042c: e50b3008 str r3, [fp, #-8] 10430: e51b2010 ldr r2, [fp, #-16] 10434: e51b3014 ldr r3, [fp, #-20] ; 0xffffffec 10438: e0823003 add r3, r2, r3 1043c: e50b3008 str r3, [fp, #-8] 10440: e51b2008 ldr r2, [fp, #-8] 10444: e51b3018 ldr r3, [fp, #-24] ; 0xffffffe8 10448: e0823003 add r3, r2, r3 1044c: e50b3008 str r3, [fp, #-8] 10450: e51b3008 ldr r3, [fp, #-8] 10454: e1a00003 mov r0, r3 10458: e28bd000 add sp, fp, #0 1045c: e49db004 pop {fp} ; (ldr fp, [sp], #4) 10460: e12fff1e bx lr00010464 : 10464: e92d4800 push {fp, lr} 10468: e28db004 add fp, sp, #4 1046c: e24dd008 sub sp, sp, #8 10470: e3a03000 mov r3, #0 10474: e50b3008 str r3, [fp, #-8] 10478: e3a03001 mov r3, #1 1047c: e50b300c str r3, [fp, #-12] 10480: e51b200c ldr r2, [fp, #-12] 10484: e3a01002 mov r1, #2 10488: e3a00001 mov r0, #1 1048c: ebffffdf bl 10410 10490: e50b0008 str r0, [fp, #-8] 10494: e51b1008 ldr r1, [fp, #-8] 10498: e59f0010 ldr r0, [pc, #16] ; 104b0 1049c: ebffff85 bl 102b8 104a0: e3a03000 mov r3, #0 104a4: e1a00003 mov r0, r3 104a8: e24bd004 sub sp, fp, #4 104ac: e8bd8800 pop {fp, pc} 104b0: 00010524 .word 0x00010524已经写好了注释,可以通过注释从main函数开始一步一步看。
标签: Linux程序崩溃分析(一)
相关文章
今天有人在家里做客吃饭,买了一瓶大瓶的可乐,有2.5L,喝了一半还剩下一半没有喝完,今天是喝不下了,扔了很可惜,不知道放到明天还可以喝吗。隔夜的可乐能喝吗?隔夜......
2023-04-30 1172
豇豆是生活中很常见的蔬菜食物,适当食用可以为人体带来很多的好处,但是也有许多要注意的地方,那么吃豇豆的好处和坏处有哪些?豇豆有什么功效?豇豆中含有的营养成分具有......
2023-04-30 1178
黑芝麻是很常见的一种食物,吃黑芝麻具有护发的作用,而且还有很多其他的功效,常吃黑芝麻对身体好处有很多,黑芝麻的吃法有很多,可以煮粥吃,还有很多其他的吃法,那么黑......
2023-04-30 1177
百合是一种较为常见的中药食物,在很多饮食中都可以添加百合,具有很好的养生功效,那么百合和什么一起煮汤好?百合与什么食物搭配最好?百合可以与很多食物一同煮汤,但是......
2023-04-30 1081
眼周围长脂肪粒一般是由于脂肪代谢紊乱、不良化妆习惯引起的。清洁完皮肤后,用消毒过的针挑出脂肪粒白头,再用棉签蘸取适量的酒精对局部消毒,防止发生感染。用质地清爽的......
2023-04-30 1071