56

LWN: 针对GCC的静态分析框架!

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=Mzg2MjE0NDE5OA%3D%3D&%3Bmid=2247484285&%3Bidx=1&%3Bsn=bdbb6d25275e4170ad5e6305674d10c4
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

关注了就能看到更多这么棒的文章哦~

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的介绍邮件里面还有一些例子,也提供了链接可以让人看到一些彩色的输出例子,例如下图。

QrIfUjq.jpg!web

除此之外,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深度文章以及开源社区的各种新近言论~

rU7JbuJ.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK