静态代码分析是指无需运行被测代码,通过词法分析、语法分析、控制流、数据流分析等技术对程序代码进行扫描,找出代码隐藏的错误和缺陷。
如参数不匹配,有歧义的嵌套语句,错误的递归,非法计算,可能出现的空指针引用等等。统计证明,在整个软件开发生命周期中,30% 至 70% 的代码逻辑设计和编码缺陷是可以通过静态代码分析来发现和修复的。
腾讯TSC团队自主研发的tscancode工具、cppcheck、coverity、clang、pclint
竞品分析的选择了3款游戏项目(约500万行代码)。
在可扩展性上,TSC有专人维护,定期根据用户需求扩展规则或新增功能特性,cppcheck和clang是开源工具,工具更新较慢,但如果用户有特殊需求可以自己扩展开发,pclint和coverity是商业软件,难以进行功能扩展。
同时,TSC有完整代码质量管理闭环平台QOC支持; coverity和clang可用web端的结果展示,但无法自行管理问题流,需要进行二次开发; cppcheck和pclint缺少web端结果展示。
摘自:https://blog.csdn.net/wetest_tencent/article/details/51516347
4.1空指针规则
空指针检查规则主要检查是否存在对赋值为空的指针解引用的情况,空指针是c/c++中最大的问题,经常造成程序崩溃的致命错误。因此,C++静态代码分析工具对空指针的检查能力显得尤为重要。
图为五个工具对样本代码扫描结果:
从报错数量和准确率来看:
有效报错数:TSC [401] >coverity[219]>>clang[57] >cppcheck[20]>pclint[14]
准确率: coverity[95%]≈TSC[92%] ≈clang[90%]>>cppcheck[28%]>pclint[14%]
综合评分: TSC[96分] >coverity[77分] >clang[56分]>cppcheck[18分]>pclint[8分]
4.2越界规则
越界一般来讲是指数组下标越界,或者缓冲区读写越界。这类错误会导致非法内存的访问,引发程序崩溃或者错误。
下图是五个工具对样本代码扫描结果:
有效报错数:coverity[98]>>TSC [18]>pclint[16] >cppcheck[6]> clang[4]
准确率: clang[100%] >coverity[80%]>TSC[70%] >cppcheck[67%]>>pclint[2%]
综合评分:coverity[90分] >TSC[54分]≈clang[55分]>cppcheck[40分]>pclint[1分]
4.3变量未初始化规则
变量未初始化顾名思义:变量声明后没有赋初值,其分配的内存值是随机的。这也是代码中容易出现的问题,会导致不确定的程序行为,造成严重的后果。
下图是五个工具对样本代码扫描结果:
有效报错数:coverity[75]>>pclint[25] >TSC [9]>cppcheck[8]> clang[1]
准确率: TSC[75%] >coverity[68%]>pclint[26%] > clang[17%] >cppcheck[3%]
综合评分:coverity[82分] > TSC[47分] >pclint[30分] > clang[10分] >cppcheck[6分]
4.4内存/资源泄露规则
内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存,从而造成了内存浪费的情况。内存泄漏是静态下很难检测的一种错误,一般需要动态分析工具进行检测,如valgrind工具会捕获malloc()/free()/new/delete的调用,监控内存分配和释放,从动态上检测程序是否存在内存泄漏。因此,静态代码分析能检查的内存泄漏就非常有限了,当前各工具主要是从代码写法上检查内存分配和释放是否配对使用。比如:fopen打开文件后在退出函数前是否有执行fclose,new[]和delete[]是否配对使用等。
下图是五个工具对样本代码扫描结果:
注:以上数据排除了cppcheck35个低价值报错,这里排除的cppcheck35个报错都是基本数据类型的new和delete不匹配(如char* p=new char[100];delete p;)虽然这种写法不规范,但由于实际上不会造成内存泄漏,很多项目不会对此进行修复。
从报错数量和准确率来看:
有效报错数:pclint[55] >TSC[40]>coverity [29]>cppcheck[28]> clang[0]
准确率: coverity[100%]=cppcheck[100%] >TSC[73%]>pclint[23%] > clang[N/A]
综合评分:coverity[79分] ≈ TSC [73分]≈cppcheck[77分]>pclint[57分]>clang[0分]
4.5逻辑错误规则
逻辑错误:指可能存在的逻辑问题,如if不同分支内容相同,在switch内缺少break等,对指针使用sizeof进行空间分配等问题。
下图是五个工具对样本代码扫描结果:
注:这些报错中剔除了一些无修改意义且结果数量很多规则:如:coverity扫描存在7484条Logically dead code(逻辑代码不可达)报错。cppcheck存在2246条unusedFunction(函数未被使用)报错。
从报错数量和准确率来看
有效数量:TSC[293]>coverity[164]>clang[142] >cppcheck [120]>pclint[116]
准确率:clang[97%] >TSC[93%]>coverity(88%)>pclint[72%] >cppcheck[55%]
综合评分:coverity[94分] > TSC[86分] > clang[80分] >cppcheck[63分] >pclint[27分]