相关情况如下:
1. 我写的A.DLL,有完整的源代码,其中使用了SDK和MFC库。
2. B.EXE,是别人写的,我没有B.EXE的源代码
3. B.EXE进程调用我写的A.DLL,注:这里A.DLL是release版
4. 在一般情况下,B.EXE加载A.DLL正常,并且运行正常,即没有任何异常;
5. 但是,当将B.EXE运行在客户的机器上,并且压力非常大的时候,有时出现类似如下的异常:
错误应用程序 B.EXE,版本 6.0.3790.3959,错误模块 A.dll,版本 1.0.0.1,错误地址 0x00003e65。上面的情况表明,出错的位置是位于A.DLL内,那么,我是否可以通过0x00003e65这个错误地址,来定位到我源代码(A.DLL)中的哪一行?具体如何操作?
谢谢!
1. 我写的A.DLL,有完整的源代码,其中使用了SDK和MFC库。
2. B.EXE,是别人写的,我没有B.EXE的源代码
3. B.EXE进程调用我写的A.DLL,注:这里A.DLL是release版
4. 在一般情况下,B.EXE加载A.DLL正常,并且运行正常,即没有任何异常;
5. 但是,当将B.EXE运行在客户的机器上,并且压力非常大的时候,有时出现类似如下的异常:
错误应用程序 B.EXE,版本 6.0.3790.3959,错误模块 A.dll,版本 1.0.0.1,错误地址 0x00003e65。上面的情况表明,出错的位置是位于A.DLL内,那么,我是否可以通过0x00003e65这个错误地址,来定位到我源代码(A.DLL)中的哪一行?具体如何操作?
谢谢!
首先,你要用adplus抓一个crash dump,参考http://support.microsoft.com/kb/286350
其次,把你dll编译时得pdb文件保存好,然后用windbg调试我学半年多觉得没入门,所以你要有非常好得心里准备
可以在客户机器上安装VC来调试,发生错误时根据“调用堆栈”来找引出错误的代码。
在客户机器上安装各类调试工具都不太现实,客户一般不会同意,再说,也是比较麻烦。
DUMP文件我也抓过,用WINDEBUG也调试过,并且定位到了具体代码的某一行,但是我感觉那一行不应该有问题。
WINDEBUG分析出的那一行是关于CMap中的Lookup操作,具体如何实现,代码实现比较麻烦,代码比较多,也不太可能把代码写在这里,我想问:CMap操作, 应该注意什么吗?特别是多线程或压力大的时候,这个还是MFC的东西,不太好调试。实在不知道有什么问题,代码也检查过多次。
或者 log记录 分析一下 估计是结构有问题
网上说debug版的不能通过
release版可以
最好不要听因为release版会忽略一些东西
而且写程序的还特意制造差异
记住一个要点:看起来正确的代码不一定真没问题,只要条件合适,它一样会有问题
另一个要点:出问题的地方往往不是导致问题的地方,所以调试没那么容易的
char buffer1[10];
CMap<int,int> * pMap = new CMap<int,int>;//假如定义个map,语法也许有问题,我不怎么用这个类
char buffer2[10];//经过30层函数嵌套调用后,你有
memset(buffer1,0,100);
memset(buffer2,0,100);//两个memset都越界//2小时后的另外一个函数内访问pMap
pMap->lookup(...);//这里代码可以说完全没有问题,但是它肯定报错。你找到出错行,不一定能找到问题
1. 每个工程师做自己代码部分代码走查,找到可能的越界地方
2. 尽量在自己机器上做各种各样的试验,也许在某个特定边界条件能试出来
3. 既然和大负荷有关,建议特别关注边界条件下(如达到上限时,多个线程同时访问时,...)记得以前某个路由器有个bug,当且仅当TCP报文长度是1038字节时就出错。如果没有足够耐心和细心,是很难发现的
这样的问题比较难,,用windbg去调试。
设上断点,运行,等停了以后,看call stack,找到是在哪个函数出了问题,然后断点设失效,再运行,等出了问题的时候,从0x00003e65处看寄存器,和模块,线程,分析问题在汇编,哪条出了问题,然后向上找call stack中你的函数,来解决
首先编译release版本的时候保留pdb文件就行了。
首先、b.exe可以调用你的debug版本吗?可以进行调试
其二、dll中同样可以加入log代码进行记录,或者打开测试通过debug view来定位出现问题的地点附加,你的动态库多线程安全吗?是否能了解一下b.exe调用你的dll的过程,以便于你定位不强壮的所在