文章目录

  • 1 前言
  • 2 什么是静态分析
  • 3 静态分析方法
  • 4 静态分析内容
    • 4.1 内存相关
    • 4.2 逻辑类
    • 4.3 编程风格与其他
  • 5 常用静态分析工具
  • 6 参考文章

1 前言

  对于大型C/C++项目,一般是以团队分模块开发的方式,代码量数十万或者更多。由于代码量的激增以及开发人员众多,代码出现bug的概率也随之增加。——这是一个数学上概率论的问题,而不是程序员的编码技术问题。其中一部分问题是非执行过程引起的静态问题,如内存泄露、内存越界、野指针、逻辑模糊、死锁等等,在发布代码前可以借助一些检测工具进行代码分析,以排除静态bug。除了检查代码静态bug外,还可以判断代码复杂度、代码质量、代码执行效率等等,作为提高代码质量的依据。

2 什么是静态分析

   程序静态分析(Program static analysis)是指在不执行代码情况下, 通过词法分析、语法分析、语义分析、控制流、数据流分析等技术对源代码进行扫描,验证代码是否满足规范性、安全性、可靠性、可维护性等指标的一种代码分析技术。 通过对代码进行审查分析,检查代码的功能、性能,提升代码质量。静态分析有两种方式,分别是人工审查和软件工具分析。

  • 人工审查,依赖于人,适合于小型项目或者代码量不大的场景;效率低、易遗漏

  • 软件工具分析,理想的方式, 准确率、可靠性、效率都远高于人工审查

3 静态分析方法

  • 词法分析,依次对代码的字符流进行扫描,通过正则表达式方法将源码转换为等价符号,并生成符号列表。

  • 语法分析,该方法主要分析源代码结构的正确性,将上下文无关联语法的符号整理成语法树。

  • 抽象语法树分析,将源代码组织生成树形结构,关联代码以树的节点表示。

  • 语义分析,主要审查结构上正确的源代码,分析代码上下文相关联的性质。

  • 控制流分析,该方法反映函数的嵌套关系,可以生成函数调用关系图;通过分析源代码,生成有向控制流图,节点表示基本代码块,节点间的有向边表示流控路径,反向边表示可能存在的循环。

  • 数据流分析,对“控制流分析”生成的控制流图进行遍历分析,记录变量初始化点和引用点,并保存为切片相关的数据信息,生成数据流图。

  • 污点分析,对“数据流分析”生成的数据流图反推断出源代码中可能受“攻击”的变量,识别代码中可能存在的缺陷。

  • 无效代码分析,“控制流分析”生成的控制流图中,无边向的孤立节点即为无效代码,通过该方法,可以检测代码逻辑问题。

4 静态分析内容

  大多数情况下,静态分析的对象都是程序源代码,少数情况会使用编译后的目标代码(可执行文件)。静态分析的内容,根据具体分析的对象,大致可以归为三类:

【1】致命类(内存相关)

【2】逻辑类

【3】编码规范与其他类

4.1 内存相关

  由于C/C++支持指针,通常有程序员来动态管理内存,这就可能导致内存泄露问题的产生。典型内存相关问题如下:

  • 访问没有申请内存的空指针(空指针)
  • 访问已释放内存的指针(野指针)
  • 内存越界访问
  • 内存泄露,申请了内存没有释放
  • 重复释放内存
  • 文件描述符泄漏(未释放)
  • 格式化字符串不安全(内存越界)

  关于内存问题的检查,也常常使用Valgrind工具检查,可参考文章如何使用Valgrind检测内存泄漏。

4.2 逻辑类

  • 逻辑错误,重复代码分支、缺少分支语句(如switch缺少break)、变量比较类型不一致、常true或false
  • 运算错误,除0运算、无符号数小于0、bool类型自加
  • 可疑检查,死循环、死锁、if语句“=”问题、返回局部变量、变量溢出

4.3 编程风格与其他

  • 编程风格,命名、规范性、可读性、可移植和复用性
  • 执行问题,函数未使用、变量未使用、代码不可到达(提前return
  • 隐患问题,语法问题、逻辑模糊问题、类型强制转换、编译警告、volatile问题
  • 效率问题,时间复杂度、空间复杂度、逻辑循环、
  • 标准行业规范,如MISRA C

5 常用静态分析工具

工具 支持语言 支持平台 权 授 说明
AdLint C Linux、Windows、Mac OS 开源 代码质量评估可视化,支持多种软体品质测量
Coverity Prevent C/C++、C#、JAVA Linux、Windows、Mac OS 付费 提供多种辅助工具,专长于最准确的找到最严重和最难检测的缺陷
Flawfinder C/C++ Linux、Windows 开源 使用用Python编写的c/c++程序安全审查工具;词法扫描和分析,内嵌了一些漏洞数据库,如缓冲区溢出、格式化串漏洞等,扫描快,按照代码中漏洞的风险等级对漏洞进行划分,可以快速找到存在的问题
Klocwork C/C++、C#、JAVA Linux、Windows 付费 国内使用较广泛的分析工具
Rats C/C++、Python、Perl、 PHP Linux、Windows 开源 扫描规则比较粗糙
PC-Lint C/C++ Windows 付费 一个由Gimpel Software公司提供的支持C/C++的商用静态分析器
Cppcheck C/C++ Linux、Windows 开源 支持图形界面和命令行
Splint C Linux 开源 静态检测针对C语言的安全工具和漏洞检测;Splint支持多种常规检查
cqual C/C++ Linux 开源 轻量级的静态分析器,可在类Linux系统下运行
BLAST C Linux 开源 采用反例驱动的自动抽象精细化方法,构建了一个抽象模型,并对模型的安全性能进行了验证的C语言分析器
Frama-C C Linux、Windows、Mac OS 开源 针对C语言的静态分析器
ITS4 C/C++ Linux、Windows 开源 Cigital公司开发的自动化源码审查工具;但它不能理解程序上下文意思,存在很大的误报
CoBot C/C++ Linux、Windows 开源 北京大学开发,中国首家通过CWE认证的软件安全检测工具
TscanCode C/C++、C#、Lua Linux、Windows、Mac OS 开源 腾讯开发的静态分析工具

推荐使用:

CoBot、TscanCode、Cppcheck、Flawfinder

  个人使用首选开源工具;付费的功能很强大,但费用都比较昂贵,适合于公司使用。

  实质上,不论是人工审查还软件分析,都可能存在一定的误报率,甚至漏报。因此,提高代码质量的根本途径在于编码过程,形成良好编码习惯,是保证代码质量的最可靠方式。

6 参考文章

【1】【代码质量】C++代码质量扫描主流工具深度比较
【2】国内外主流静态分析类工具汇总

原文链接:https://blog.csdn.net/qq_20553613/article/details/108608856

最后修改日期:2020年9月19日