Ctrl+F5与F5的疑惑

来源:互联网 发布:hangman游戏 c语言 编辑:程序博客网 时间:2024/04/27 14:42

    最近几天一直在搞个程序导致死机的问题。以前或许只是在调试几百行,上千行左右的代码,这是自己第一次接触比较大型的代码,大概上千万行的程序,以前自己用的那一套方法只是适用于一些小程序。

    因为这个问题自己觉得比较“奇怪”,只有在运行状态(Ctrl+F5)的环境下会导致死机,而在debug(F5)的时候,却不会死机,觉得有点不可思议。

    好了,现在问题表象就是这样。以前的经验是把函数逐个屏蔽掉,看下代码执行的情况。可现在上千万行的代码,去屏蔽哪个呢?郁闷了好久。后来问了下鬼佬同事,也搞不定,这个可能是内存覆盖问题,有个叫boundchecker的工具,具体没用过,听说可以检测到内存泄露之类的问题。后来用了自己平台的一个内存检测的工具,实现的原理与boundchecker类似。用了那个工具之后,果然发现了程序死的地方,找到了对应的那个语句,这里用A语句代替。在运行模式下通过插入调试信息,证明程序是死在A语句上。

    下来便是如何修改程序的问题,似乎快把问题解决了。可A语句用的是一个第三方的库函数,没有办法看到实现的代码,传入参数是个指针。查看堆栈,查看上下文,似乎总是找不到什么特别的地方。开始纠结中。。。

    后来请教了一个非常有经验的老同事,这个问题可能是内存覆盖,或悬垂指针导致的,即大名鼎鼎的野指针。在调试模式下不死,在运行模式下死,这其实也不是什么神奇的事情,在他看来,是经常可以见到的,不过我至今未明白。

    因为程序如此庞大,而且无法在F5下去查看内存,能够去做的,便是在程序中去插入一些调试信息,通过这些信息来判断程序运行状态。原理是这样,比如一个文件有100行代码,去屏掉前50行,让它跑,看他死不死。再打开前50行,跑后50行,看他死不死,通过不断的去做一些假设的猜想,去寻找问题所在,这是或许有运气的成分在里面,不过确是实践之中最高效的方法。因为这些程序去读懂它所花的成本是非常高的,而且很可能看了半天还读不懂。

    自己重新理了一下思路,后来让yx同鞋过来,猜想了一个可能出问题的地方,在那个函数中写了调试信息,刚好不死了,欣喜若狂。后来花了一下午的时间,找到了那行真正导致死机的代码,顿时松了口气。原来是同样的指针给free了两次,soga!

    继续走下去,这个地方跟之前发现死机的A语句,貌似没有半点关系。为什么呢?自己猜想,A语句,是一个需要大量分配内存的操作,而free了两次,肯定是破坏了某块内存,所以多数情况是在A语句的时候死掉。这样解释似乎比较符合实验结果。

    各位大侠们,若是有类似经验,请告之原因,不胜感激!