1.应用程序测试代码

测试代码如程序清单 1.1所示:

程序清单 1.1

#include <stdio.h>

 

int main (int argc, char **argv)

{

sleep(2);

volatile int *a = (int *)0x40; //设置物理地址

 

printf("value = %x\n",*a); //读取物理地址中的值

*a = 0x12; //设置物理地址中的值

 

return (0);

}

  2.模拟器运行结果

在mini2440模拟器上的运行结果如图 2.1所示:

SylixOS内存错误排查方法_ 内存错误

2.1模拟器运行结果

  • 标号1处表示测试程序的加载地址,这里为0x60030000

  • 标号2处表示引起错误的那条指令在内存中的地址,这里为0x600302ec

  • 标号3处表示引起内存访问错误的地址,这里是0x40,意思是系统进行了一个访问0x40这个内存地址的操作,从而导致了内存错误

  • 标号4处表示内存访问错误类型,这里是can not write,意思就是系统执行了一个写内存的操作,但是这个内存地址是不允许写的,从而引起内存错误


    3.反汇编测试程序


    本测试程序是用debug模式编译所得,将测试程序和sylixos-objdump工具拷贝到同一个目录下,如图 3.1所示:

    SylixOS内存错误排查方法_SylixOS_02

    3.1拷贝测试程序和反汇编工具

    在空白处按住shift并右击,选择"在此处打开命令窗口",如图 3.2所示:

    SylixOS内存错误排查方法_SylixOS_03

    3.2打开命令窗口

     

    在打开的命令行中输入:arm-sylixos-eabi-objdump.exe -S -d 2440_test_app >app.dis,在同一目录下将生成一个app.dis反汇编文件,如图 3.3所示:

    SylixOS内存错误排查方法_ 内存错误_04

    3.3生成反汇编文件


    4.分析反汇编文件


    由之前分析得知,测试程序的加载地址=0x60030000,引起错误的那条指令在内存中的地址=0x600302ec。所以可以计算出引起错误的那条指令在内存中的偏移为0x600302ec-0x60030000=0x2ec。这个地址就是引起错误的那条指令在反汇编文件的汇编地址,如图 4.1所示:

    SylixOS内存错误排查方法_SylixOS_05

    4.1查看反汇编文件

    可以看出0x2ec汇编地址处对应的是一条写内存指令,对应的c语句是"*a = 0x12",这就是源码中出错的地方。通过这个测试也发现了SylixOS下的一个有意思的地方,那就是非法地址可以读,但是不能写。