博客 阅读时间 5 分钟

充分利用 C/C++ 静态分析工具

分享本文
Make the most of the C/C++ static analysis tools

静态代码分析是检测软件源代码缺陷的过程。静态分析工具对于检测常见的编码错误很有用;使用它们的好处包括:

  • 让源代码更易读、更易维护。
  • 防止运行时出现意外行为。
  • 提升执行性能。
  • 让代码更安全。

有许多 C/C++ 静态分析工具可供选择,每种都专注于特定领域,各有优势。例如:

  • CppCheck
  • Clang Analyzer
  • Visual C++ Analyzer
  • VERA++
  • Goanna
  • Viva64
  • PCLint

探索这些工具的结果有几种方式:

  • XML 格式:这些工具都可以生成 XML 文件,可以用来创建 HTML 报告,或被其他工具消费以探索分析结果。
  • HTML 格式:HTML 是生成报告并与团队分享的便捷格式,您还可以使用 XSL 样式表创建自定义报告。
  • IDE 插件:几乎所有知名的 IDE 都为这些工具提供了插件,可以直接在源代码中查看违规情况。

代码质量工具的问题之一是,它们往往会用大量并非真正问题的问题——即误报——淹没开发者。当误报出现时,开发者会逐渐学会忽略工具的输出,甚至彻底放弃使用它。

为了更好地探索这些工具的结果,我们需要一种方法,只关注相关的发现,并为开发者提供清晰的结果视图。

CppDepend 和 CQLinq

CppDepend是另一个静态分析工具,可以与其他工具互补。它使用基于 LINQ 的代码查询语言(CQLinq),像查询数据库一样查询代码库。

CppDepend 默认集成了 Cppcheck、Vera++ 和 Clang 分析器,还可以通过其 API 轻松扩展以支持其他静态分析工具。Visual Studio Analyzer 插件的源代码是开放的,展示了如何集成其他工具。

让我们以 Clang 源代码为例,看看如何使用 CppDepend 探索这些工具的结果。

获取所有问题:

检索所有问题的查询非常简单。然而,正如您所见,这并不是很有用——事实上,处理一个包含 331417 个问题的结果是一项挑战。

static1

为了更好地处理这些工具的结果,我们可以对它们进行过滤,只关注我们想要的内容。

按工具查询

我们可以修改第一个查询,为相关工具添加条件。

static2

报告最频繁的问题

了解哪些问题被这些工具最频繁地报告,是很有意思的。

static3最常见的是 Vera++ 报告的风格问题;如果它们在您的情况下不相关,我们可以将它们从查询中排除。

问题最多的类

了解哪些类包含大量违规是非常有意思的。

static4

前面的查询很有意思,但它并不能准确告诉我们哪些类的质量问题最严重。另一个值得考虑的有用度量是代码行数(NBLinesOfCode)。我们可以修改前面的查询,计算问题数量与 NBLinesOfCode 之间的比率。

static5

被广泛使用且存在问题的方法

当静态分析工具报告问题时,了解哪些问题应该优先处理是很有用的,尤其是当它们涉及 Bug 时。一个 Bug 可能存在于某个特定的方法中,但有意思的问题是:有多少方法受到这个 Bug 的影响。被广泛使用的方法会被更多代码调用,最好尽快解决它们的问题。

static6

使用 CQLinq,我们可以将所有这些工具的结果以及 CppDepend 的结果组合起来,创建更精细的查询,并将这些检查加入构建流程。

问题趋势

软件项目中出现问题并不罕见;任何项目都可能有需要解决的问题。然而,我们应该监控项目的质量趋势。事实上,如果问题数量随着项目的变更和演进而增长,这是一个不好的信号。CppDepend 提供了趋势监控(Trend Monitoring)功能来创建趋势图。

趋势图是基于分析过程中随时间记录的度量值构建的。默认提供 50 多个趋势度量,创建您自己的趋势度量也很容易。

通过这张趋势图,我们可以监控 Cppcheck 问题随时间的演变:

cppcheck7

将静态分析工具的结果集成到 HTML 报告中

CppDepend 允许在 HTML 报告中附加额外的报告章节,列出一些 CQLinq 查询。


在 CQLinq 查询资源管理器(CQLinq Query Explorer)面板中,被加入报告的 CQLinq 分组会用橙色矩形框标出。

cppcheck10

在 HTML 报告中,可以从菜单访问这些附加章节:

cppcheck11

将静态分析工具的结果集成到构建流程中

CppDepend 引入了关键 CQLinq 规则(Critical CQLinq Rule)的概念。关键规则提供了一种定义高优先级规则的方式,这些规则绝不能被违反。借助关键规则,可以在发生关键规则违规时中断构建流程。

关键规则就是勾选了Critical Rule(关键规则)标志的 CQLinq 规则:

在构建流程中,当关键规则被违反时,CppDepend.Console.exe会返回非零退出码。可以利用这一行为,在关键规则被违反时中断构建流程。

我们可以轻松定义一条 Cppcheck 关键规则,在发现特定类型的 Cppcheck 问题时中断构建。

结论

CppDepend 对其他静态分析工具持开放态度,您还可以轻松集成自己的自定义工具。这样,您就能利用 CppDepend 的所有功能,更好地探索受支持的 C/C++ 静态分析工具的结果。

分享本文