在基于KEIL的项目开发过程中,会遇变量值与预设的运行结果不一样,在挂上仿真器debug了n个小时,排除了所有逻辑问题后,发现似乎这个值被意外更改了,但是要找到是谁修改了他却不好下手。现提出一种查找此类问题的方法——利用map文件查找越界。
首先需要设置map的输出,在MDK-ARM的Option for Target—Output Listing的标签页中设置需要输出的map文件内容,如图:
在工程编译完成后在设置的目录下会生成项目名.map的文件。大致来说map到可以分为如下几个部分:
- Section Cross References:模块、段的交叉引用关系;
- Removing Unused input sections from the image:移除未使用的段;
- Image Symbol Table:映射符号表,列出了各个段所存储的对应地址;
- Memory Map of the image:映像的内存分布;
- Image component sizes:映像组组件大小。
解决越界数据修改问题我们主要关注的是Image Symbol Table部分。例如:
含义为: - Symbol Name:符号名称
- Value:存储对应的地址;
0x0800xxxx指存储在FLASH里面的代码、变量等。
0x2000xxxx指存储在内存RAM中的变量Data等。 - Ov Type:符号对应的类型
符号类型大概有几种:Number、Section、Thumb Code、Data等; - Size:存储大小
- Object(Section):当前符号所在段名
现假设在调试中的一个全局变量u8 g_testFlag数值与逻辑总是不符,那么就可以怀疑被意外修改了,在map文件中搜索g_testFlag,看到在g_testFlag所在地址前是一个u8 upgradeFileName[15]。那么问题就很可能是upgradeFileName操作是越界了。
查找代码中发现存在如下操作,
memcpy(upgradeFileName,“MyUpgradeFile001.bin”,21);
upgradeFileName被memcpy后,越过了它的size范围,而修改了邻近地址的g_testFlag。
类似的,还有for循环操作数组越界,memset操作内存越界等,都可以以这种方法来找到问题。
结尾
今天主要介绍KEIL中使用map文件查找越界问题。如有不同见解,欢迎留言讨论。
扫描上方二维码关注“嵌入式案例Show”公众号,看更多嵌入式案例