【IT168 技术文文档】
软件质量的重要性和必要性已被越来越多的软件开发人员所认识,各种质量保障工具和流程层出不穷。从根本上讲,软件是通过程序代码实现的,是代码质量的外在表现。只有提高代码质量,才能从根本上提高软件的质量。要保证并提高代码质量,可以从多个角度入手,譬如良好的设计、统一的编码规范、强化的代码评审、有效的代码静态分析等,除此之外,我们还应该从代码运行分析入手,发现软件的性能和内存瓶颈,保证代码的运行质量。
通常而言,除了功能实现以外,影响代码运行质量的原因可以归为三种类型:
·内存问题,如在用户使用时程序死机或者突然崩溃;
·代码覆盖率问题,如发现的问题没有被测试过;
·性能问题,如与大量数据或者特定的数据相关的运行速度变慢的问题;
上述问题,必须在应用程序运行期间,借助于代码运行分析工具,通过收集和研究运行时数据,加以预防,以提高代码运行质量。
内存分析
运行时内存错误和泄漏是应用程序中最难检测的问题之一,也是最难分析和修复的,因为内存泄露源和错误的表现是分离很远的,很难将导致错误的原因和最终的效果联系起来。仅仅通过检查源代码是很难预测和理解这些错误发生的可能性和发生的情景的。此外,这些错误通常出现在特定条件下,很难复现。通常,这需要相当多的调试才能发现导致内存错误的程序逻辑和设计。
在测试中进行内存分析,将会增加组织的总体效率,应该使内存分析成为习惯。因为通过使用内存分析工具收集相关数据,可以大大减少开发人员花在调试和寻找问题所在的时间。
在下面的例子程序中,在第5行分配内存时,忽略了字符串终止符"\0"所占空间导致了第8行的数组越界写(Array Bounds Write)和第9行的数组越界读(Array Bounds Read);在第7行,打印尚未赋值的str2将产生访问未初始化内存错误(Uninitialized Memory Read);在第11行使用已经释放的变量将导致释放内存读和写错误(Freed Memory Read and Freed Memory Write);最后由于str3和str2所指的是同一片内存,第12行又一次释放了已经被释放的空间 (Free Freed Memory)。
2 using namespace std;
3 int main(){
4 char* str1="four";
5 char* str2=new char[4]; //not enough space
6 char* str3=str2;
7 cout<<str2<<endl; //UMR
8 strcpy(str2,str1); //ABW
9 cout<<str2<<endl; //ABR
10 delete str2;
11 str2[0]+=2; //FMR and FMW
12 delete str3; //FFM
13 }
上面的代码虽然包含许多难以发现的内存错误,但可以编译连接,而且可以在很多平台上运行。如果这些内存错误不经排除,在特殊配置下触发,会造成不可预见的错误。
借助一些高级内存调试工具,可以快速准确定位导致这些内存泄露错误的原因,大大减少调试的时间和复杂性。Purify即是此类工具之一,它既可以检查不同的模块,确保它们能够正确地共同工作,又可以揭示出在单独开发期间不明显的代码的依赖关系。下图是一个采用Purify生成的C++应用程序的自动化测试报告。
对于C和C++程序来说,Purify的报告是类似MLK(Memory Leak,内存泄漏)、ABW(Array Bounds Write,数组边界写)、ABR(Array Bounds Read,数组边界读取)等警告、错误和信息。每个这种Purify的缩写都表示一种应用程序中出现的内存错误,在此一并列出,由此可窥一斑: