解决方法(一)介绍的方法比较麻烦,因为需要反汇编要排查文件,当文件比较大时,反汇编的时间就会很长,而且打开一个很大的文件在性能较差的电脑上也需要较长时间,下面介绍一种更简便的方法。
1. 测试代码
测试代码如下:
#include <stdio.h> int main (int argc, char **argv) { volatile int *a = (int *)~0x0; //设置物理地址 printf("value = %x\n",*a); //读取物理地址中的值 *a = 0x12; //设置物理地址中的值 return (0); }
2. 运行程序
2.1 设置系统环境变量
在命令行输入如下命令,这样在app运行的时候就可以自动打印出各个模块的加载信息,我们主要需要的是模块的基址信息:
VPROC_MODULE_SHOW=1
2.2 运行结果
从图中可知,app程序的崩溃的地址是0x091dd30a,app程序的基址是0x091dd000。
2.3 计算崩溃地址偏移值
崩溃地址的偏移值=0x091dd30a - 0x091dd000=0x30a。
3. 使用addr2line工具获取崩溃代码的位置
将addr2line工具和待分析的程序文件(release或者debug的都可以,但不能是strip版本的)拷贝到同一目录下:
打开一个cmd终端,输入如下命令:
i386-sylixos-elf-addr2line.exe -e addr2line_test -f 30a
其中30a就是之前计算出的崩溃地址的偏移值,-f表示打印崩溃代码所在的函数名字:
从图中可以看出,崩溃的代码是在源文件addr2line_test.c中的第7行,所在的函数是main函数,结合源码看下:
从源码中可以看出,第7行代码访问了一个非法地址,这就是程序崩溃的地方。
2021年9月17日 17:51 1F
打卡