静态代码检查
什么是静态代码检查
静态代码检查,又被称为静态程序分析(Static program analysis)
静态 是指在 不运行计算机程序 的条件下,进行程序分析
大部分的静态程序的分析的对象是针对 特定版本的源代码,也有些静态程序分析的对象是 目标代码
为什么做静态代码检查
静态代码检查可以不运行程序就为我们定位出来一些问题,这些问题会导致一些潜在的风险(如下表)
潜在问题
风险
重复代码过多
造成开发人力的浪费以及后期维护成本增加
编码风格糟糕
代码凌乱、不可读,难于维护与开发修改
圈复杂度过高
造成代码可维护性、可继承性降低,问题定位难度加大
编码安全风险
使用具有安全风险的函数,导致系统的安全性层级降低,加大系统的安全风险
静态代码检查关注点
编号
检查点(举例)
概述
1
重复率
表示一段源代码在一个程序,或者一个团体所维护的不同程序中重复出现,是不希望出现的现象
2
代码风格
程序开发人员所编写源代码的书写风格,良好代码风格的特点是使代码 易读
3
圈复杂度
衡量一个模型判定结构的复杂程度,数量上表现为独立线性路径条数,圈复杂度大说明程序代码可能质量低且难于测试和维护
4
代码安全
编码过程中,常见的安全问题包括(不限于):缓冲区溢出/跨站脚本攻击(XSS)/SQL 注入/XML 注入/LDAP 注入
静态代码检查常用分析技术
编号
分析技术
概述
1
词法分析
从左至右一个字符一个字符的读入源程序,对构成源程序的字符流进行扫描,通过使用正则表达式匹配方法将源代码转换为等价的符号(Token)流,生成相关符号列表
2
语法分析
判断源程序结构上是否正确,通过使用上下文无法语法将相关符号整理为语法树
3
数据流分析
对控制流图进行遍历,记录变量的初始化点和引用点,保存切片相关数据信息
4
无校代码分析
根据控制流图可分析孤立的节点部分为无效代码
5
抽象语法树分析
将程序组织成树形结构,树中相关节点代表了程序中的相关代码
6
语义分析
对结构上正确的源程序进行上下文有关性质的审查
7
控制流分析
生成有向控制流图,用节点表示基本代码块,节点间的有向边代表控制流路径,反向边表示可能存在的循环;还可生成函数调用关系图,表示函数间的嵌套关系
8
污点分析
基于数据流图判断源代码中哪些变量可能受到攻击,是验证程序输入、识别代码表达缺陷的关键
代码检查的常用工具
编号
检查工具
概述
1
Splint
Splint 是开源的静态软件缺陷检测工具,用于检测用 标准C 实现的软件缺陷
2
Klocwork K8
支持 C/C++,Java,它能检测缓冲区溢出、内存泄漏、安全漏洞等软件缺陷
3
Coverity
第一个能够快速、准确分析当今的大规模(几百万、甚至几千万行的代码)、高复杂度代码的工具。检测和解决 C、C++、Java 和 C# 源代码中最严重的缺陷的领先的自动化工具
4
Findbugs
是一个基于 Java 语言的静态分析工具,它主要检查类或者 jar 文件
5
PMD
采用 BSD 协议发布的 Java 程序代码检查工具,其核心是 javacc 解析器
6
Cppcheck
一种开源的 C/C++ 代码缺陷静态检查工具,只检查编译器检查不出来的 bug,不检查语法错误
代码检查的企业实践
代码检查已经被集成到华为的软件生命周期当中,作为其中的重要一环存在
不通过代码检查就无法合入代码仓库
在个人级和版本级的流水线当中,都会被自动触发执行
通过多年的开发经验,现已积累了大量的代码检查规则,并将这些经验能力提供至华为云DevCloud平台的CodeCheck当中
静态代码检查的效果
静态代码检查前
如何找 Bug?
单元测试,黑盒测试,代码审查
资源约束
人力有限:人员的质量(测试人员的能力水平、素质等),投入回报比等
时间有限:产品快速迭代,发布周期短,个人时间有限
空间有限:测试用例检查范围小,测试覆盖率不够大
精力有限:人类大脑精力等有限
静态代码检查后
如何找 Bug?
静态代码检查
克服约束
在不运行程序的前提下找出问题
不依赖于好的测试用例(对人员的素质要求有所降低)
不单单测试单个代码片段【全路径覆盖】
不需要知道软件到底想干什么
CodeCheck
CodeCheck 多语言检查
支持混合语言检查
CodeCheck 问题可视化
CodeCheck 规则集管理
自定义规则集
集中管理并共享规则集
CodeCheck 误报与漏报统一管理
Others:
误报率高
误报优化难
误报问题重复报
CodeCheck:
支持跨函数的深度检查
标记误报后不会再报
预置规则集误报率低
部分误报持续优化
什么叫误报?
在代码检查的过程中,发现某个东西有问题报错,我们进行审核的时候再看,同样是没有问题,这就是误报
CodeCheck 特性
一站式
覆盖主流语言和标准
SDLC 集成:提交代码时、合并代码时,会触发流水线当中的静态代码检查环节
专业性
提供专业级的预置规则集
提供专业的缺陷修复建议
支持跨函数的深度检查
缺陷精确定位到代码行
多分支检查
可自由切换分支进行检查
聚焦新问题
在每个任务的基础上可以设置新问题起始时间(默认起始时间为当前任务上一次检查成功的时间,起始时间之后检查出的所有问题属于新问题)
责任自动归属
静态分析过程中,自动将新问题分配给问题代码行上的 最后一次提交者
问题协作
可以与他人分享问题链接,提升协作便利性
CodeCheck 产品典型操作流程
创建代码检查任务
选择代码仓库
选择检查语言
完成任务创建
执行代码检查任务
任务主页点击开始检查
等待任务检查完成(查看检查进度)
查看检查结果
任务详情 —— 概览视图
任务当前分支:默认为 master 分支
任务最近检查时间
未检查问题数、未解决新问题数、已解决问题数
代码平均圈复杂度、代码重复率、有效代码行数
未解决问题严重程度统计
问题最多 Top 10 检查规则
问题指派分布统计
任务详情 —— 问题视图
过滤器功能:提供按问题级别、问题状态、问题检测时间、规则、文件目录、负责人过滤
单个问题卡片:包含问题所在文件、问题报错信息、问题级别、状态、负责人、修改建议等
问题可操作区域:可手动更新问题状态、问题负责人、查看问题修改建议等
问题关键代码片段
任务详情 —— 代码度量视图
代码度量指标(可切换过滤)
对应指标下的具体数据列表
任务详情 —— 设置视图
任务名称、检查语言等的更新
选择代码检查任务的规则集
自定义执行计划
自定义任务通知(比如检查完成时通知)
自定义新问题初始时间等
删除当前任务
思考题
以下对于 Git Rebase 和 Merge 两种合并方式的区别,哪些选项描述是正确的?
A. Merge 是一个合并操作,会将两个分支的修改合并在一起,默认操作的情况下会提交合并中修改的内容
B. Rebase 的提交历史忠实地记录了实际发生过什么,关注点在真实的提交历史上面
C. Rebase 并没有进行合并操作,只是提取了当前分支的修改,将其复制在了目标分支的最新提交后面
D. Merge 的提交历史反映了项目过程中发生了什么,关注点在开发过程上面
答案:AC
最后,欢迎大家关注我的个人微信公众号 『小小猿若尘』,获取更多IT技术、干货知识、热点资讯。同时,我在公众号中分享了精心整理的一些视频资料(包括 Python全栈教程、AI教程、前端、数据库等),大家回复相应关键词即可获取网盘视频链接,感谢大家的关注😊