作者:猪可夫司机 | 来源:互联网 | 2023-10-13 12:19
最近一段时间一直忙于开发新平台系统的功能,今天测试那边拿过来简单的测试一下,并对相关需求和功能点进行验证。结果出现了一个奇怪的问题:在验证某个功能点时,在release模式下的程
最近一段时间一直忙于开发新平台系统的功能,今天测试那边拿过来简单的测试一下,并对相关需求和功能点进行验证。结果出现了一个奇怪的问题:在验证某个功能点时,在release模式下的程序频繁出现奔溃现象。之前在开发该功能点时也进行了充分的测试,程序一直运行正常,怎么一到release模式下就出现频繁奔溃的现象呢?
由于还在新功能的开发过程中,本想测试中的小问题可以留到后面正式测试时再解决,毕竟时间点比较紧,实现既定的功能是第一位的。但是对于这种频繁奔溃的问题,测试那边肯定很是恼火的,就连我自己也看不过去了,时间再紧也得先解决这个问题。于是,仔细走读了上述功能点的代码,也没发现什么问题,而且要命的是debug下没有发生奔溃的问题。其实也知道,这可能是与程序在debug下和release下的不同特性导致的,比如:变量在debug下即使没有初始化,编译器也会去初始化,而在release下则不会,会使用随机值;debug下有大量调试信息,有内存保护,出现奔溃的几率要小一点,而release下却没有这样的保护。 本来在程序中植入了华生医生,以便在程序出现异常时利用华生医生产生的日志文件,结合IDA工具对异常点进行定位。但是不幸的是,在出现奔溃的时候并没有产生日志文件,这样就比较棘手了。由于debug下很难复现,release下又没有奔溃日志,加上系统的代码量很大,只能修改工程在release下配置,在release下进行调试了。结果在release下调试很快找到了问题,问题在于某行代码对空指针操作了。那么既然是空指针,那么debug下和release下的截然不同的表现作何解释呢?出问题的代码与上述功能点没直接的联系,于是找到相关责任同事,让其查一下其负责的模块,怎么出现了对空指针操作的情况。待找到可能的出错的代码点时,我过去看了一下,结果终于可以真相大白了:同事定义的变量,由于使用了if判断语句导致if内的语句没有执行导致变量没有初始化,在debug下没问题,因为编译器会对该变量初始化,而在release下变量中存放就是随机值了,导致接下来的if判断语句条件为真,进入了出错的函数中去了,从而导致程序的奔溃(在出错的函数中并没有对指针进行是否为NULL的判断)。这就很好解释了为什么程序在debug下和release下的不同表现了。
花了很大的精力才最终解决上面的问题。从中我们也能总结一些东西:平时写代码一定要规范,变量一定要初始化,指针变量要做是否为NULL的判断等等。由于这个同事是刚毕业的,编码经验相对比较少,一方面代码不够规范,另外代码没有进行仔细的走读才导致了上面的问题。所以,我们平时还是要多强调编码的规范性,特别是对刚毕业的新同事,应该更要强调这一点,因为规范性在提高代码可读性的同时,也可以减少代码出错的几率。这点在大型系统的开发中也尤为重要。
下面给出在VC6.0中如何在release模式下进行调试的办法。只要在工程的C++ tab页面和Link tab页面中进行如下的配置就可以了。
1、在C++ tab页面中:
category:General
Optimizations:Disable(Debug)
Debug info: program database
如下所示:
2、在Link tab页面中:
category:General
勾选 General debug info
勾选 General mapfile
如下所示: