【问题标题】:Capture all compiler invocations and command line parameters during build在构建期间捕获所有编译器调用和命令行参数
【发布时间】:2018-07-29 21:26:37
【问题描述】:

我想为在make 的帮助下构建的大型软件项目运行静态 C/C++(可能还有 Python、Java 等)代码分析工具。众所周知,make(或任何其他构建工具)为指定的源代码文件调用编译器和类似工具。也可以通过定义环境变量来控制编译,以便稍后通过其参数传递给编译器。

准确静态分析的关键是提供与传递给编译器完全相同的定义和包含路径(基本上是它的所有-D-I 参数)。这样,该工具将能够遵循编译器遵循的相同代码路径。

问题是,项目的高度复杂性意味着无法静态确定这样的环境,因为不同的文件是使用不同的定义/包含路径和其他编译标志集构建的。

这个想法是,应该有可能以某种方式捕获编译器的单个调用,并为每个输入文件传递给它的所有参数。有了这些信息并在其直接过滤之后(例如,不需要知道-O 优化级别或-W 警告设置),应该可以使用相同的一组定义/包含为每个输入文件调用静态分析器只针对那个输入文件。

问题是:是否有现有的工具/工作流程可以实现我所描述的想法?我最感兴趣的是针对 POSIX 系统的解决方案,但也欢迎针对 Windows 的想法。 p>

我自己的一些想法。

  • 最简单的解决方案是收集make 输出并在之后处理它。但是,某些项目的 makefile 规则可以提供非常简洁的输出而不是冗长的输出,因此可能需要对 Makefile 进行一些修补,这并不总是可取的。并行构建也可能将它们的控制台输出混合在一起并且无法解析。适应其他构建系统 (Cmake) 也并非易事,因此远非最方便的方式。

  • ptrace 下运行make 并记录与启动新应用程序相对应的exec* 系统调用的所有调用,包括编译器调用。然后需要解析ptrace 的输出。这种方法与构建系统和语言无关(将捕获对任何语言的任何编译器的所有调用)并且应该适用于并行构建。然而,它似乎在技术上更复杂。由于ptrace 坐在make 的背上,构建过程的性能下降也不清楚。将其移植到 Windows 也将更加困难,因为那里的程序跟踪 API 有所不同。

  • Windows 上的 C++ 专有静态分析器(以及最近的 Linux AFAIK)PVS-Studio 似乎实现了第二种方法,但欢迎详细说明他们是如何做到的。如果有其他 IDE/工具已经有类似我需要的东西,请分享它们的信息。

【问题讨论】:

  • Android NDK 是一个基于 make 的框架,支持命令行参数V=1 回显所有编译和链接命令。以同样的方式检测您的 makefile 应该不会很困难。
  • @AlexCohn 是的,我知道 Makefiles 允许这样做;我们的项目中有相同的V=1 选项。问题是关于将静态分析器集成到大项目中的更一般的解决方案。直接为单源文件程序运行编译器是微不足道的;但是对于多文件源,人们使用make 代替。静态分析器也是如此——它很容易用于玩具项目,但对于具有复杂源代码树的项目,最好以编排方式运行。
  • make -d 或 make SHELL='/bin/sh -x'

标签: c++ c makefile static-analysis ptrace


【解决方案1】:

在Linux中收集编译参数信息的方法有以下几种:

  1. 覆盖环境 CC/CXX 变量。它用于 Clang Analyzer 的实用程序 scan-build。此方法仅适用于 Make 的简单项目。

  2. procfs - 所有进程信息都存储在 /proc/PID/... 中。从磁盘读取是一个缓慢的过程,您可能无法收到有关构建的所有进程的信息。

  3. strace 实用程序(ptrace 库)。这个实用程序的输出包含很多有用的信息,但它需要复杂的解析,因为信息是随机写入的。如果您不使用许多线程来构建项目,那么这是一种收集有关进程信息的相当可靠的方法。在 PVS-Studio 中使用。

  4. CMake 中的 JSON 编译数据库。您可以使用定义-DCMAKE_EXPORT_COMPILE_COMMANDS=On 获取所有编译参数。如果项目不依赖非标准环境变量,这是一种可靠的方法。此外,CMake 项目可能会出现错误并发出不正确的 Json,尽管这不会影响项目构建。 PVS-Studio 支持。

  5. Bear 实用程序(使用 LD_PRELOAD 进行函数替换)。您可以获得任何项目的 JSON 数据库编译。但是如果没有环境变量,就不可能为某些项目运行分析器。此外,您不能将它用于已经使用 LD_PRELOAD 进行构建的项目。 PVS-Studio 支持。

收集有关在 Windows 中为 PVS-Studio 编译的信息:

  1. Visual Studio API 获取标准项目的编译参数;

  2. MSBuild API 获取标准项目的编译参数;

  3. Win API 用于获取任何编译过程的信息,例如 Windows 任务管理器。

【讨论】:

  • Bear 的方法是我最初错过的一个选项 - 谢谢!也会看scan-build详情。
【解决方案2】:

VERBOSE=true 是一个默认的 make 选项,用于显示带有所有参数的所有命令。例如,它也适用于 CMake。

您可能想查看Coverity。他们将他们的工具附加到编译器以获取编译器收到的所有内容。您可以覆盖环境变量CCCXX 以首先收集所有内容,然后照常调用编译器。

【讨论】:

  • 了解(通用术语)Coverity 如何完成它的工作,即附加到编译器会很有趣。
  • 我怀疑它使用了特定于平台的调试选项;对选项的支持因平台而异。
猜你喜欢
  • 2015-03-14
  • 2016-10-04
  • 2020-07-23
  • 1970-01-01
  • 2014-11-07
  • 2021-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多