相关情况如下:
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.   

    这个不能用vc调试,得要用windbg
    首先,你要用adplus抓一个crash dump,参考http://support.microsoft.com/kb/286350
    其次,把你dll编译时得pdb文件保存好,然后用windbg调试我学半年多觉得没入门,所以你要有非常好得心里准备
      

  2.   

    0x00010000之前是系统保留的地址空间,这里不会有代码,所以不能通过0x00003e65来定位到源代码。
    可以在客户机器上安装VC来调试,发生错误时根据“调用堆栈”来找引出错误的代码。
      

  3.   

    出错位置时在 A.DLL 里面,但不一定代表你得 A.DLL的 代码有问题(当然,有可能不太健壮,即容错能力及处理能力上还有缺陷)。比如,有可能是 B.EXE 给 A.DLL 中的函数传入了不恰当的参数,导致 A.DLL 中的某个函数执行出现了错误。如果没有 B.EXE 的源程序,了解 B.EXE 的工作过程也会对调试有所帮助。但要凭光release版本执行时出错的地址来判断,基本上是很难的。除非使用debug类的工具,看函数进栈出栈以及机器码来推测,但这样也只是推测而已,无法准确定位。如果有时间和精力,楼主不妨试试反向工程?
      

  4.   

    谢谢各位。
    在客户机器上安装各类调试工具都不太现实,客户一般不会同意,再说,也是比较麻烦。
    DUMP文件我也抓过,用WINDEBUG也调试过,并且定位到了具体代码的某一行,但是我感觉那一行不应该有问题。
    WINDEBUG分析出的那一行是关于CMap中的Lookup操作,具体如何实现,代码实现比较麻烦,代码比较多,也不太可能把代码写在这里,我想问:CMap操作, 应该注意什么吗?特别是多线程或压力大的时候,这个还是MFC的东西,不太好调试。实在不知道有什么问题,代码也检查过多次。
      

  5.   

    a.dll是你自己写的 里面加入输出信息  可以在ide环境下看见
    或者 log记录 分析一下 估计是结构有问题
    网上说debug版的不能通过
    release版可以
    最好不要听因为release版会忽略一些东西
    而且写程序的还特意制造差异
      

  6.   

    windbg分析的那一行应该有所帮助,你应该看看那个CMap的this指针是不是为NULL
    记住一个要点:看起来正确的代码不一定真没问题,只要条件合适,它一样会有问题
    另一个要点:出问题的地方往往不是导致问题的地方,所以调试没那么容易的
      

  7.   

    一个简单的例子:
    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(...);//这里代码可以说完全没有问题,但是它肯定报错。你找到出错行,不一定能找到问题
      

  8.   

    arong1234 , 你的例子我也看懂了,呵呵,我也怀疑过是其它的地方有溢出,代码也都分析过了,该判断NULL的地方都加上了,可就是没找到问题,调试相当的困难。
      

  9.   

    靠找到出错行往往不能解决问题,几个建议:
    1. 每个工程师做自己代码部分代码走查,找到可能的越界地方
    2. 尽量在自己机器上做各种各样的试验,也许在某个特定边界条件能试出来
    3. 既然和大负荷有关,建议特别关注边界条件下(如达到上限时,多个线程同时访问时,...)记得以前某个路由器有个bug,当且仅当TCP报文长度是1038字节时就出错。如果没有足够耐心和细心,是很难发现的
      

  10.   

    关注中
    这样的问题比较难,,用windbg去调试。
      

  11.   

    其实C51更简单吧,有个watchdog就可以了。
      

  12.   

    客户机上装上VC或者OD,,然后调试,关联上你那个A。EXE,然后暂停程序,把模块和线程都打开,在反ASM里的0x00003e65
    设上断点,运行,等停了以后,看call stack,找到是在哪个函数出了问题,然后断点设失效,再运行,等出了问题的时候,从0x00003e65处看寄存器,和模块,线程,分析问题在汇编,哪条出了问题,然后向上找call stack中你的函数,来解决
      

  13.   

    将你的dll在编译时生成Map文件,再借助Dr. Watson来调试,可以定位到错误行。
      

  14.   

    WINDEBUG没有用过,我一般用vs2005来调试DUMP,一般都可以根据堆栈来分析找到问题
    首先编译release版本的时候保留pdb文件就行了。
      

  15.   

    两个问题
    首先、b.exe可以调用你的debug版本吗?可以进行调试
    其二、dll中同样可以加入log代码进行记录,或者打开测试通过debug view来定位出现问题的地点附加,你的动态库多线程安全吗?是否能了解一下b.exe调用你的dll的过程,以便于你定位不强壮的所在