我自持也写了XX行的代码,调试经验也不可谓不强大笑。但是最近遇到的这个bug,却
着实让我头疼了一会...错!不是一会,是3天啊!
    具体是这样的,在开发windows下的gdb GUI调试环境时,使用thread PIPE与gdb mi
接口交互,在winodows 7下编写代码。上周五突然遇到一个问题:就是程序运行着就会突
然崩溃。马上用ollydbg作为系统默认活动调试器,在崩溃后立即调试进程,发现错误点
随机出现在主线程和PIPE READ线程中,而且指令在ntdll中出错。并且看不到调用链,
不能回溯到我的程序中去,这说明不是我的程序直接引发的,而是“间接”引发的问题。
    奇怪的事来了,如果我用wingdb调试其他的pe文件不会出错,只有特定的那一个pe
文件必错。比这个pe文件大或小的文件都不错,单单这个pe文件会错。而且只在向gdb
mi发送特定的cmd时才会错,使用其他cmd不会错:
   

代码:
read_str_4a_cmd(&g_npp,"set disassembly-flavor intel\n",buf_tmp,&size,5000);  //err!  
      
 read_str_4a_cmd(&g_npp,"set\n",buf_tmp,&size,5000); //ok!
第一条指令返回的string长度要大于第二条。而且还有更郁闷的事,在debug模式下
运行程序,啥错都没有,怎么都不崩!调试最痛苦的事莫过如此....
    由于在windows7下调试安全保护不便的原因所以我尝试在xp下调试,看能不能找
到问题根结。更奇怪的事来了,在双核系统xp下没有出错!而且我原来的windows7
是单核的系统,我原以为可能是多线程同步的问题,这时觉得也不像。
    不能就此放过, 不能幻想是系统的bug,不是我的。并且念上10000句fxxk后,回去
肆虐TA发泄!我再一次回到windows7系统上,最小化出错点(就像我不止一次在汇编及
C区说的那样),编写对应的单元测试,增加PRINT DEBUG语句,不是一条两条的加,
而是几十条的加。因为MinGW调试有限,所以换了调试也很有限的Code::Blocks,不过
比MinGW好点。使用VS 20xx的各位可能会暗自窃喜:叫你不用VS IDE。我承认在这个
方面如果我最初用VS开发,也许调试起来就会快很多。也许吧...但我不能也不打算在回
到那个VS IDE中去,原因使用GCC的各位同仁自然懂得...
    言归正传,在用最简化的UNIT TEST测试后,发现崩溃出在C库函数free()里。在经
历了N多的反复递进调试中后(就像在魔兽3中从zero开始建基地那样),终于发现根本
问题所在:在N多的malloc和赋值和free中,一个赋值往末尾多赋了一个'\0',就是这一个
byte导致C heap链表被破坏,使得最终在某次的free中(主线程或PIPE Thread)发生崩溃
。然而为什么只有特定的文件,特定的指令才会崩溃,我想这个只能感谢GOD让我遇到
了那个出错的文件,并且出错了。因为这种错误和未初始化的变量一样属于“随机”情况。
细心的朋友可能还不放过,会问:那在XP下为什么不出错?这个很简单,因为win7的
安全性和鲁棒性(如果我让你产生了联想,那么我换一个词:健壮性大笑)比xp要高,
that's why!!!
    末了我想再说几句,如果用NT的debug heap和若干wingdb选项的话,我还用这么费
劲吗???呜呜呜...不过没事了,重要的是我会记住"调痛",我可以GO ON了,呵呵。


                                                                                                         侯佩|hopy
                                                                                                   2011.08.08 1428