C ++静态代码分析工具值得吗?

时间:2009-03-12 17:38:24

标签: c++ static-analysis

我们的管理层最近一直在与一些销售C ++ static analysis tools的人交谈。当然销售人员说他们会发现大量的漏洞,但我对此持怀疑态度。

这些工具如何在现实世界中发挥作用?他们发现真正的错误吗?他们是否帮助更多初级程序员学习?

他们值得这么麻烦吗?

14 个答案:

答案 0 :(得分:28)

静态代码分析几乎总是值得的。现有代码库的问题在于它可能会报告太多错误,使其开箱即用。

我曾经参与过一个项目,该项目有来自编译器的100,000多个警告......在该代码库上运行Lint工具没有意义。

使用Lint工具“正确”意味着购买更好的流程(这是一件好事)。我最好的工作之一是在研究实验室工作,我们不允许在警告中检查代码。

所以,从长远来看,这些工具是值得的。在短期内,将编译器警告转到最大值并查看其报告的内容。如果代码是“干净的”,那么现在就是查看lint工具的时间。如果代码有很多警告...优先级并修复它们。一旦代码没有(或至少很少)警告,那么请查看Lint工具。

因此,Lint工具不会帮助一个糟糕的代码库,但一旦你拥有一个良好的代码库,它可以帮助你保持良好。

编辑:

对于100,000+警告产品,它被分解为大约60个Visual Studio项目。由于每个项目都删除了所有警告,因此它被更改,以便警告是错误,这可以防止将新警告添加到已清理的项目中(或者更确切地说,让我的同事对任何已签入的开发人员发出正义的吼叫代码没有先编译它:-)

答案 1 :(得分:10)

根据我与几位雇主的经验,Coverity Prevent for C / C ++显然是值得的,即使在优秀的开发人员代码中也会发现一些错误,以及最糟糕的开发人员代码中的许多错误。其他人已经涉及技术方面,因此我将关注政治困难。

首先,代码最需要静态分析的开发人员最不可能自愿使用它。所以我担心你在实践和理论上都需要强有力的管理支持;否则它可能最终只是一个清单项目,以产生令人印象深刻的指标而不会实际修复错误。任何静态分析工具都会产生误报;你可能需要专门用一些人来减少他们的烦恼,例如,通过分类缺陷,确定检查器的优先级,以及调整设置。 (商业工具应该非常擅长不要多次出现误报;仅此一点可能是物有所值。)即使真正的缺陷也可能产生烦恼;我对此的建议不用担心,例如,签到的评论抱怨显然破坏性的错误是“次要的”。

我最大的建议是上面我的第一条法则的必然结果:首先考虑廉价镜头,然后看看你最糟糕的开发者那些痛苦明显的错误。其中一些甚至可能是由编译器警告发现的,但是很多错误可能会漏掉这些漏洞,例如,当它们被命令行选项抑制时。真正明目张胆的错误在政治上是有用的,例如,有一个最有趣的缺陷的十大列表,如果仔细使用,它可以很好地集中思想。

答案 2 :(得分:5)

确实有帮助。我建议你试用一个试用版并运行你认为被忽略的代码库的一部分。这些工具会产生很多误报。一旦你了解了这些,你可能会发现缓冲区溢出或两个可以在不久的将来节省大量的悲伤。此外,尝试至少两个/三个品种(以及一些OpenSource的东西)。

答案 3 :(得分:5)

正如一对人所说,如果你在大多数应用程序中运行静态分析工具,你会得到很多警告,其中一些可能是误报或可能不会导致可利用的缺陷。正是这种体验导致人们认为这些类型的工具是嘈杂的,也许是浪费时间。但是,有一些警告会突出显示可能导致安全性,可靠性或正确性问题的真实且潜在危险的缺陷,对于许多团队而言,这些问题对于修复很重要,并且几乎不可能通过测试发现。

也就是说,静态分析工具可能非常有用,但将它们应用到现有代码库需要一些策略。以下是一些可能对您有帮助的提示..

1)不要一次打开所有内容,决定一组初始缺陷,打开这些分析并在代码库中修复它们。

2)当您解决一类缺陷时,请帮助您的整个开发团队了解缺陷是什么,重要的原因以及如何编写代码来抵御该缺陷。

3)完全清除代码库中的那类缺陷。

4)一旦修复了这类问题,就引入一种机制来保持零问题状态。幸运的是,如果您在基线没有错误,确保不重新引入错误要容易得多。

答案 4 :(得分:4)

我使用过它们 - 例如PC-Lint,他们确实找到了一些东西。通常它们是可配置的,如果你确定xyz确实不是问题,你可以告诉他们“不要再烦我xyz了”。

我不知道他们帮助初级程序员学到了很多东西,但是它们可以作为一种机制来帮助收紧代码。

我发现第二组(持怀疑态度,探测错误)眼睛和单元测试通常是我看到更多错误发生的地方。

答案 5 :(得分:4)

这些工具确实有帮助。 lint一直是C开发人员的理想工具。

但我提出的一个反对意见是,它们是在您编写了大量代码并可能生成大量消息后运行的批处理过程。

我认为更好的方法是在IDE中构建这样的东西,让它在你编写时指出问题,这样你就可以立即纠正它。不要让这些问题首先进入代码库。

这是Java的FindBugs静态分析工具和IntelliJ的Inspector之间的区别。我非常喜欢后者。

答案 6 :(得分:4)

您可能不得不处理大量的误报,特别是如果您的代码库很大。

大多数静态分析工具使用“程序内分析”,这意味着他们单独考虑每个程序,而不是考虑整个程序的“整个程序分析”。

他们通常使用“程序内”分析,因为“整个程序分析”必须考虑通过一个实际上不会发生的程序的许多路径,因此通常会产生假阳性结果。

程序内分析通过仅关注单个程序来消除这些问题。但是,为了工作,他们通常需要引入一个“注释语言”,用于描述过程参数,返回类型和对象字段的元数据。对于C ++,这些东西通常是通过用你装饰东西的宏来实现的。然后注释描述诸如“this field is never null”,“此字符串缓冲区由此整数值保护”,“此字段只能由标记为'background'的线程”等来访问。

然后,分析工具将获取您提供的注释,并验证您编写的代码是否符合注释。例如,如果您可能将null传递给标记为非null的内容,则会标记错误。

在没有注释的情况下,该工具需要假设最坏的情况,因此会报告很多并非真正错误的错误。

由于您似乎尚未使用此类工具,因此您应该假设您将不得不花费大量时间来注释您的代码,以消除最初报告的所有误报。我最初会运行该工具,并计算错误的数量。这应该可以估算出在代码库中采用它需要多长时间。

该工具是否值得,取决于您的组织。你最喜欢什么类型的错误?它们是缓冲超限错误吗?它们是空取消引用还是内存泄漏错误?他们是线程问题吗?它们是“oops我们没有考虑那种情况”,或“我们没有测试我们的产品在立陶宛版本的Windows 98上运行的Chineese版本?”。

一旦你弄明白问题是什么,那么你应该知道这是否值得付出努力。

该工具可能有助于缓冲区溢出,空取消引用和内存泄漏错误。如果它支持“线程着色”,“效果”或“权限”分析,它可能有助于线程化错误。然而,这些类型的分析是相当尖端的,并有巨大的标志负担,所以他们确实带来一些费用。该工具可能无法帮助解决任何其他类型的错误。

因此,它实际上取决于您编写的软件类型,以及您最常遇到的错误类型。

答案 7 :(得分:3)

如果您使用正确的工具,我认为静态代码分析非常值得。最近,我们尝试了Coverity工具(有点贵)。它很棒,它带来了许多关键缺陷,这些缺陷未被棉绒或净化检测到。

我们还发现,如果我们之前使用了覆盖率,我们可以避免35%的客户现场缺陷。

现在,Coverity在我的公司推出,当我们在旧的软件版本中获得客户TR时,我们正在对其进行覆盖,以便在我们开始分析之前为故障提供可能的假设。< / p>

答案 8 :(得分:2)

当有一些非常优质的免费分析工具时,可能不需要支付大部分静态分析工具(除非您需要商业版提供的一些非常特殊或特定的功能)。例如,请参阅我就另一个关于cppcheck的问题给出的答案。

答案 9 :(得分:2)

我想这取决于你的编程风格。如果您主要编写C代码(偶尔使用C ++功能),那么这些工具可能会有所帮助(例如内存管理,缓冲区溢出......)。但是如果你使用更复杂的C ++特性,那么在尝试解析你的源代码时,这些工具可能会混淆(或者因为C ++工具通常使用起来更安全而找不到很多问题)。

答案 10 :(得分:2)

与答案所依赖的一切一样......如果你是唯一为你奶奶打造针织图案漂亮打印机的开发人员,你可能不想购买任何静态分析工具。如果你有一个中等规模的软件项目会进入重要的事情,也许最重要的是你的日程安排很紧,你可能想稍微投入一些,以便以后节省更多。

我最近写了一篇关于此问题的一般性咆哮:http://www.redlizards.com/blog/?p=29

我应该在时间允许的情况下尽快写下第2部分,但一般会做一些粗略的计算是否值得你:

  • 花在调试上的时间是多少?
  • 绑定了多少资源?
  • 静态分析可以找到多少百分比?
  • 工具设置的成本?
  • 购买价格?
  • 安心吗? : - )

我个人的看法也是:

  • 早期进行静态分析

    • 项目早期
    • 在开发周期的早期
    • 早在早期(在夜间构建和后续测试之前)
  • 为开发人员提供自己使用静态分析的能力

    • 没有人喜欢被测试工程师或一些匿名工具告知 他们昨天做错了什么
    • 减少调试让开发人员满意: - )
    • 提供了一种学习(微妙)陷阱而不会感到尴尬的好方法

答案 11 :(得分:2)

使用Elsa和Oink完成了这个相当惊人的结果。

http://www.cs.berkeley.edu/~daw/papers/fmtstr-plas07.pdf

&#34; Debian Linux中格式化字符串漏洞的大规模分析&#34; 作者:Karl Chen,David Wagner, 加州大学伯克利分校, {quarl,daw} @ cs.berkeley.edu

摘要:

格式字符串错误是一种相对常见的安全漏洞,可能导致任意代码执行。与其他人合作,我们设计并实现了一个系统,使用类型定量推理来消除整个Linux发行版中的格式字符串漏洞,这是一种可以发现违规行为的静态分析技术。我们成功分析了Debian 3.1 Linux发行版中66%的C / C ++源代码包。我们的系统发现1,533格式字符串污染警告。我们估计其中85%是真正的积极因素,即真正的错误;忽略库中的重复,大约75%是真正的错误。我们建议该技术可以在不久的将来使格式字符串漏洞消失。

类别和主题描述符D.4.6 [操作系统]:安全和保护 - 入侵软件; 一般条款:安全,语言; 关键词:格式字符串漏洞,大规模分析,类型平均推断

答案 12 :(得分:1)

发现真正的错误的静态分析是值得的,无论它是否是C ++。有些人往往会非常吵,但是如果他们能够捕获像签名/无符号比较这样的细微错误,导致破坏代码或超出数组访问的优化,那么他们肯定是值得的。

答案 13 :(得分:0)

在前雇主,我们有Insure ++。 它有助于确定Valgrind无法找到的随机行为(使用未初始化的东西)。但最重要的是:它有助于消除尚未被称为错误的错误。

Insure ++很好但价格昂贵,这就是我们只购买一个用户许可证的原因。