在Coverity里,分析流这个概念通常对应着一个具体的代码分支、一条版本线,或者某个固定的构建入口;所以一个项目底下往往可以挂上好几个不同的stream,比如main主干一个,release发布分支一个,feature特性分支再单独一个,分别用来接收和存放各自的扫描结果。要是对stream的管理不够上心,最容易碰到的问题就是缺陷被稀里糊涂地交到了错误的分支里,修复状态在几个地方看起来对不上,或者同一个CID在不同版本的stream之间根本没办法放在一起比对。Coverity Connect在stream收到新的缺陷数据时,会专门生成一份snapshot,后面所有关于结果的对比,也基本都是围绕着snapshot和stream的范围来展开的。
一、Coverity怎么管理分析流
给分析流命名的时候不能太随意,它的名字最好是跟代码分支、发布版本或者某一条产品线严格对应起来,这样后面按范围去查看缺陷的时候才会一目了然。
1、根据分支来建立stream
管理员可以先在Coverity Connect里头,为一个项目分别创建不同的stream,比较常见的安排是主干单独占一个stream,发布分支再独占另一个stream,那些需要长期维护的老分支也各自建立自己独立的stream;但临时拉出来的开发分支不建议一个个全都建成长期stream,否则等到后面快照和权限堆得越来越多,再去管理就会变得非常吃力。
2、在提交扫描时把stream选对
每次执行扫描提交任务的时候,都得确认一下命令行或者流水线的配置里,用的是不是那个正确的stream名称,比如主干代码就应该提交到main这个stream,发布分支的代码则提交到release_1.0那里去;一旦不小心交错了stream,页面上可能就会冒出来“当前分支没有新增缺陷”,或者“早就改好的旧分支里忽然又多出一批问题”这种假象,干扰判断。
3、按不同的团队来配置权限
当各个团队只需要查看和审计自己负责的那几个stream时,完全可以按照项目和stream的层级,给不同的角色配置不同的权限;这样一来,开发人员就不会不小心把别人分支里的缺陷状态给改掉,安全或者质量的负责人也能够按照自己的需要,集中去查看全部的stream状态,互不干扰。
二、Coverity分析流切换后结果怎么对比
在切换了分析流以后,缺陷数量出现一些变化其实是很正常的,因为不同的stream它们背后对应的代码范围、编译选项、规则配置还有历史审计状态,极有可能都是不一样的。
1、先去看snapshot列表
可以进到目标stream里面,去打开Snapshots这个页面,每次stream收到一批新的缺陷数据时,系统都会自动生成一个新的snapshot,并且把Snapshot ID和创建时间清清楚楚地记录下来;在开始对比之前,一定得先把两个stream里到底要比较的是哪一次扫描的结果给确认好,别拿着一个旧快照去跟一个新快照放在一起,然后就直接下定论。
2、利用snapshot comparison来进行比较
Coverity本身支持通过snapshot comparison这个功能,把筛选的范围给构造出来,用来比较不同快照之间缺陷发生了哪些差异,比如某次扫描新增了哪些问题、消失了哪些问题,或者有哪些问题一直都没有被修掉;如果要做跨stream的比较,那也得先看准这两个snapshot分别来自哪一个stream,免得只是在同一个stream内部翻来翻去,反而忽略了分支本身带来的差异。
3、去查看By Snapshot视图
在Issues的By Snapshot视图里面,我们可以按照快照范围去查问题,根据官方文档里的说明,这个视图可以调整scope,把一系列的snapshot全都展示出来或者放在一起比较,也可以把不同stream里边的snapshot拉到同样的视图里对比;这就很适合用来判断切换了stream之后,哪些问题是新冒出来的,哪些只是跟不同分支的历史差异有关。
三、Coverity结果对比异常怎么排查
一旦发现对比出来的结果跟自己预想的不太一样,先别急着去怀疑工具本身,因为大多数情况都是因为stream选错了、构建时的配置不同,或者审计状态并没有按照预想的那样子继承下来。
1、检查构建时的命令是不是一致的
不同的stream如果用的是不同的编译参数、不同的宏定义、不同的依赖路径,甚至是不同的规则配置,那最后扫描出来的结果肯定是不一样的,所以在做对比之前,应该先把构建脚本、cov-build的参数、analyze用到的规则,还有最终提交到的目标stream都仔细对一遍。
2、看看同一个CID在不同的stream里是不是表现一致
有的时候,相同的代码问题在不同stream里面,CID可能是相同的,但也有可能会因为代码结构发生了变化而被重新识别成一个新的CID,所以在对比的时候不能光盯着总数看,得挑几个具体的CID打开,去核对其中的文件路径、函数名、缺陷类型,还有出现的具体位置,看这些细节是不是都对应得上。
3、检查审计状态是不是被分开维护了
缺陷的分类和标记状态,一般都是跟着stream以及仓库的配置走的,在某个stream里面被标记成了误报,可不代表另一个stream也自动跟着变成了误报;如果团队希望多个分支之间的状态要保持同步,那就得提前规划好审计仓库和审计流程要怎么打通。
4、把对比用的基准给保存下来
每次在正式对外发布之前,可以把项目名称、stream、snapshot ID、扫描时间、规则配置还有各项缺陷的统计数据,都一并记录下来;等到后面再去做分支之间的对比时,手里就有一份明确的参照基准,不至于光凭当前页面上临时显示的数字来判断好坏。
总结
对于Coverity里要怎么去管理分析流,以及切换了分析流以后结果该怎么去对比,这里头的关键就在于,要把stream跟代码分支、发布版本一一对应好,在扫描提交的时候填对正确的stream名称,并且按照不同的团队来设置好权限;在做结果对比的时候,得先把snapshot确认清楚,然后再借助By Snapshot视图或者snapshot comparison功能,去看看哪些缺陷是新增的、哪些是消失的、哪些是一直保留下来的。要是碰到数据出现异常的情况,第一时间应该去查stream名称填对了没有、构建参数有没有不同、规则配置是不是一致、CID的具体位置是否变化,还有审计状态是分开维护的还是同步的,千万别把配置上的差异误判成代码质量本身发生了突变。
