在程序开发时,时常会遇到异常报错的情况。有时因为环境因素,通过调试工具很难在调试时复现故障情况,或者很难在短时间内复现故障情况。随着工程代码量的增加,定位程序出错位置变得更加困难。
在使用基于WINCE平台的英创系列工控主板进行应用程序开发时,当程序产生异常退出,CE操作系统将通过调试串口打印类似如下错误信息。根据这些信息,结合应用程序对应的map文件,就能够快速定位程序异常的位置,本文将详细介绍这一方法。
准备工作
以一个简单的控制台程序test_exception.exe为例,模拟会产生异常的程序,代码如下。
#include 'stdafx.h'
#include 'windows.h'
#include 'commctrl.h'
void testErr(char* pbuf, int len)
{
*(pbuf+len) = len;
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
int i;
char* p = 0;
char buf[10];
for (i=0; i< 10;i++)
{
printf('i=%d\n',i);
testErr(buf, i);
Sleep(1000);
}
printf('test err\n');
Sleep(1000);
testErr(p, 10);
for (;;)
{
printf('.');
Sleep(1000);
}
return 0;
}
这段代码有个非常明显的致命错误,char* p = 0;实际上是定义的是p的地址为0,之后testErr(p, 10);函数对p地址的操作会造成指针越界,程序将产生异常结束。
设置工程属性
首先需要设置工程属性,让工程编译时产生MAP文件。
另外还可以选择添加汇编输出信息。
这样我们在重新编译程序后,就可以在编译目录里找到源文件的.map和.cod两种调试辅助文件。
记录DEBUG信息
连接英创主板的调试串口至PC主机的串口,打开串口工具(英创主板默认的调试串口参数为115200,8-N-1),以监听DEBUG口打印信息。
运行test_exception程序,记录DEBUG口打印的异常信息。
主要记录出错的exe(或者dll)名test_exception.exe,PC地址00011024,和RA地址000110bc。
查看map文件
查找PC地址00011024,和RA地址000110bc附近的信息。
对照PC地址能够知道,testErr函数的地址00011000,这个函数地址偏移00011024-00011000的地方出错了。
对照RA地址能够知道,最后一次调用该函数未出错时的位置,在wmain函数地址偏移000110bc -00011034的地方。
这样,我们不但知道了是哪个函数出的错,也知道了在哪里调用出的错。
查看cod文件
为了进一步确定范围,打开编译目录下对应的cod文件test_exception.cod。
查看testErr函数信息,可以知道,在偏移地址00011024-00011000=00024的地方的汇编,以及出错的C代码,为test_exception.cpp第10行的*(pbuf+len) = len;
查看wmain函数信息,可以知道,返回地址000110bc -00011034=00088,最后一次正常调用testErr的地方是在test_exception.cpp第22行。
定位错误
这样稍加分析,我们就可以确定出错位置了。
最后,可以在代码附近添加打印或日志log记录,来验证异常位置判断是否正确。
需要例程可以联系英创工程师。
如果产生异常提示信息的不是用户程序,而是'coredll.dll',则判定为是驱动出错,请联系英创工程师检查出错原因。
全部0条评论
快来发表一下你的评论吧 !