项目里面只要夹杂了第三方库、自动生成的代码、测试用的桩模块,还有那些为了兼容老版本而保留的历史目录,这些内容并不一定都要被Coverity扫进去。这时候我们就得弄明白两件事:Coverity里到底怎么去设置忽略目录的规则,以及当这些规则加好以后,如果发现忽略路径并没有生效,又该从哪些地方开始排查。这里的一个关键,是先分清当前所做的忽略到底发生在整个流程的哪一个阶段。比较常见的处理方式,可以是在代码被捕获之前就直接把它排除掉,也可以在分析环节启动之前再把它移除掉,还可以到Coverity Connect里去用组件映射的办法,把那些我们不打算花精力去管的问题归拢起来。按照Black Duck社区里一些资料的说法,coverity_config.xml里面的skip_file这个配置项,就能够用来排除那些既不想提交发射、也不打算让分析器去碰的文件和目录。
一、Coverity怎么设置忽略目录
在动手设置忽略某一个目录之前,先要判断清楚这个目录是不是真的不需要做分析。比如第三方拿来的库、编译过程生成出来的文件目录、示例性的代码,还有给单元测试做辅助的代码,这几类东西通常是可以考虑排除掉的;但是像核心的业务代码,就不要为了图一时告警数量变少而随手给排除出去,那样反而可能把真正的隐患给盖住了。
1、在配置文件里直接排除
如果希望某些文件从一开始的捕获阶段,直到后面的分析阶段,全程都不进到结果里面,那就可以在Coverity的配置文件当中把跳过的规则加上去。在填写路径规则的时候,最好把路径写得尽可能完整一些,不要只简简单单地填一个目录名字,否则有可能把其他地方同名的目录也一并不小心给排除了。
2、在分析阶段再做排除
有的项目倾向于先让Coverity做一次完整的捕获,把该抓的东西都抓到,然后再趁着正式分析开始之前,把那些确实不需要的文件给拿掉。根据Black Duck社区的资料,可以在cov-build或者coverity capture这一步跑完之后,在cov-analyze这一步还没开始之前,去处理掉那些不想让它进入分析范围的文件,把控制点往后挪了一步。
3、在Connect中用组件来管理
如果文件实际上已经被分析完了,只不过我们单纯不想把第三方库引发的那些问题放进团队整改的清单里,那就可以转到Coverity Connect里面,去利用项目的组件管理或者组件映射的功能,把它设置成忽略状态。这种做法对缺陷管理更友好一些,不一定非得去削减本地捕获的内容,也方便团队筛选问题时直接跳过。
4、在流水线里把规则固定下来
在持续集成这条流水线上,可不要每次都靠人临时去改一条命令,这样既容易错也记不住。更好的办法是把那些需要排除的目录,写进一份统一的配置文件,或者写进扫描脚本里面,再把这份配置文件跟当前项目分支、构建命令一起,搁到版本管理工具里去,让每一次跑流水线的时候都按照同一套规矩来。
二、Coverity忽略路径不生效怎么排查
如果发现加好的忽略路径规则并没有按预想的那样把目录滤掉,常见的原因主要就是三种:要么是路径的写法跟实际捕获到的路径根本就没有对得上,要么是配置文件写好之后压根就没被正确加载进来,要么就是忽略的阶段从一开始就给挑错了。
1、先去看实际捕获到的路径到底是什么
打开cov-build跑完以后产生的那份日志,或者看看中间目录里留下来的信息,去核对一下Coverity记录下来的文件路径,究竟是绝对路径还是相对路径,起点到底是哪里。因为你写在排除规则里的路径,必须要去跟这个实际记录的路径匹配,而不是去匹配你脑子里以为的那个源码目录,这一环不对,后面的规则再怎么改都是擦肩而过。
2、检查一下路径里面的分隔符
Windows和Linux这两套系统,路径的写法是不一样的,要是流水线实际是跑在一个Linux的容器里面,而规则却按照Windows那套管用盘符的写法去填,那显然就不会命中。比较统一的做法是,规则写成什么样子,就照着实实在在跑扫描的那个环境里的路径格式来。
3、确认配置文件到底有没有被加载
如果用的是自定义的配置文件,那就得自己去确认一下,cov-build、cov-analyze,或者相关的那些扫描命令,是不是真的把这份配置文件作为参数给带进去了。因为cov-analyze会在之前指定的那个中间目录里面去运行检查器,并且把分析的结果存下来,所以扫描命令和它对应的中间目录,这两样东西必须能够严格对上,一个指东一个指西肯定是行不通的。
4、把源文件和头文件区分开
还有一种容易让人困惑的情况,就是某个目录虽然已经被排除掉了,但它里面的头文件还是被别的源文件通过#include给引用了进去。你在分析结果里看见这个路径,并不代表这个文件被当成独立的源文件又分析了一遍,它很可能仅仅是被包含了一下,因此在缺陷路径当中出现了一下,这不等于排除规则就失效了。
三、Coverity忽略目录后怎么复核
当排除的规则全部加完之后,不能只看总的告警数量是不是噌地掉下来了就认为万事大吉了。还得去验证一下,核心代码有没有被误伤给一起排除掉了,同时第三方那些目录是不是也不再往外冒新的问题了。
1、去翻一翻分析文件的列表
每次重新完成一轮扫描过后,就要去抽查一下报告里面出现的文件路径,看看那些本应该被排除掉的目录,是不是真的不再作为主要的缺陷位置蹦出来了。要是仍然能看到,那就顺着日志回去,再核一遍路径到底有没有被规则打中,看看是哪一层没有防住。
2、把排除前和排除后的结果拿来对比
可以把这一轮排除前后,缺陷的总数量、涉及到的文件个数,还有高风险问题的数量,放在一起比一比。要是发现数量一下子断崖似的掉下去,那就得警惕这些规则是不是被写得太宽了,会不会一刀切的时候连带着把核心业务代码也一起给排除出去了,这个光靠数字的变化就能嗅出不少问题。
3、把每一条排除的理由都留下来
对每一条加上去的排除规则,都建议用简短的文字写清楚这个目录是干什么用的、由谁负责、因为什么原因要把它排除掉,比如说第三方源码不纳入整改范围、自动生成的代码不安排人工维护、测试桩目录不进入最终的交付范围等等,这样后面交接的时候别人也一眼就能看懂。
4、定期去复查一遍这些规则
项目总是在不断往前推进的,目录结构隔一段时间可能就会发生变化,旧的那些排除规则可能会慢慢失效,也可能反过来,不小心覆盖到了新冒出来的目录。比较让心的做法是,在版本快要发布之前,专门去查一次排除清单,看看它是不是还跟当前的代码结构能够贴合得上,别让过期的规则留在那里误导人。
总结
Coverity怎么设置忽略目录,以及忽略路径不生效时该怎么排查,大致的处理顺序可以这样固定下来:先把忽略到底要发生在捕获阶段、分析阶段,还是只在Connect里做缺陷管理这件事明确好;接着再去核对实际的扫描路径、配置文件有没有被正确加载、操作系统里面的路径格式是不是一致,以及头文件被包含进来这种情况有没有造成干扰;等到排除规则确认生效之后,还要把扫描的文件列表和缺陷数量拿来跟前一个版本比一比,不要只图告警数量的下降,却把那些真正需要被检查的代码也一股脑儿排除出去了。
