关注了就能看到更多这么棒的文章哦~
A static-analysis framework for GCC
By Jake Edge
December 4, 2019
原文来自:https://lwn.net/Articles/806099/
GCC比起Clang/LLVM编译器来说其实在某一方面一直比较弱,不过很快就能补上了。在11月中旬,David Malcolm发到gcc-patches mailing list的邮件,介绍了他写的一个针对GCC的全新的静态分析架构(static-analysis framework)。这可能标志着针对GCC编译器的一系列代码分析功能的开始。
在这封很长的邮件里面,有介绍这个静态分析工具会是基于GIMPLE static single assignment (SSA) intermediate representation(静态单赋值中间表示)的一轮interprocedural analysis (IPA,过程间分析)。它用到了状态机来代表所在解析的代码,这个分析过程会寻找发生一些错误的状态转换的情景。这种状态转换就表明应该弹出warning信息提醒用户这里可能代码有问题。
这个patch set里面增加了两种独立的检查器(checker):malloc()指针跟踪,以及检查通过stdio使用FILE * API的时候是否有问题。还有一些其他的概念验证性的状态机:一个是跟踪敏感信息的,例如password密码,需要想办法避免泄露到log文件里;另一个是跟踪可能被篡改了的输入数据避免用在数组下标上(避免数组越界访问)。
这个malloc()状态机在sm-malloc.cc中实现的,它会检查是否有那些常见的错用了malloc()返回的指针的问题,例如重复释放(double free)、空指针引用(null dereference)、针对一个非heap的指针调用了free()等等。类似地也有另一个patch增加了sm-file.c用来检查FILE *问题,主要是查看是否有多次调用fclose()或者是否close文件的时候出错了。
这些诊断性输出信息的处理,需要一些额外功能来支持这些新的warning类型。例如,为了能提供更加易懂的warning信息,就需要确定出来导致这个问题的代码路径并且保存好。这个信息会和warning信息以及代码位置(行号以及行内偏移)一起被记录下来,这样就可以被编译器展示出来。patch的介绍邮件里面还有一些例子,也提供了链接可以让人看到一些彩色的输出例子,例如下图。
除此之外,Malcolm还扩展了诊断工具,可以允许在warning信息这里增加更多的附属信息(metadata)。具体来说,它把这些信息跟Common Weakness Enumeration (CWE) list关联了起来,当然也可以关联其他类型的metadata。在支持CWE的终端terminal里面,CWE编号会是一个可以点击的链接,能跳转到这个条目对应的网页上,例如:https://cwe.mitre.org/data/definitions/690.html
分析的过程是通过传递--analyzer命令行参数来触发的,还有一些参数能打开或关闭具体的某一类warning信息。目前这个功能是实现为GCC的"in-tree"插件的,也就是会随着GCC本身分发出去。不过Richard Biener建议最好直接把分析器编译到GCC里面去,当然可以有一个配置选项来选择关闭它。他还提到可以考虑重写GCC插件API,是否能让插件跟GCC和LLVM都可以配合工作。不过这肯定会需要更长时间来实现了。
Malcolm说,他实现成插件API,主要是因为认为目前代码还不成熟:“我这样实现的原因,是因为分析器还是一个中端(middle-end)代码,不过不如其他的中端代码成熟,当然我会继续改进的。我希望能有什么方法把这个代码标记成technology preview的状态,这样人们就可能愿意来体验一下了,同时也能有意识认识到这里可能会有bug,只不过早点提供出来大家可以先试试。......我采用in-tree插件的方式,是因为看到一些类似的前端(frontend),不过确实如果编译进GCC的话会更简单一些,通过编译时的配置来选择。这里有几千行C++代码,不算小了,并且也有相关的selftests和DejaGnu测试。”
目前来说,这个分析器的代码大概导致GCC代码增加了2.5%。不过Jakub Jelinek和Biener还是更倾向于直接编译进GCC。Malcolm看起来也挺乐意,所以不久后应该会切换进来。同时,他还提交了一个更新版本的patch set,主要是修复一些编译时优化(LTO, link-time optimization)的兼容性问题。
Patch的描述邮件最开始的Rationale小节里面,介绍了这个分析器的动机以及目标:“如果在编译器里面集成一个检查器,会有不少好处,开发者就能在开发代码的时候看到这些诊断信息了,而不是在后面的阶段。我认为,如果分析器运行得足够快的话,大家可能会更愿意利用起来拿到更多更深入但是也更耗时的warning信息。(我预计会在2倍左右的编译时间,因为我感觉这个代价比起面对各种指针混乱等bug来说还是比较值得的。)”
总的来说,目前大家的反馈还比较正面。已经有不少code review意见了。正如Eric Gallager所说,过去多年来一直有用户要求增加一些warning信息,而这个分析器能够对此有帮助。目前来看,GCC的这个缺失功能是会慢慢补上了。希望几年内,--analyzer能够在自由软件领域里面广泛应用起来。这样肯定会帮咱们的项目产生更好的代码。
全文完
LWN文章遵循CC BY-SA 4.0许可协议。
欢迎分享、转载及基于现有协议再创作~
长按下面二维码关注,关注LWN深度文章以及开源社区的各种新近言论~