写点什么

C/C++ 编译命令捕获机制及实现

作者:maijun
  • 2023-09-01
    新加坡
  • 本文字数:1375 字

    阅读完需:约 5 分钟

基于编译实现的 SAST 工具,需要能够获取原生项目的构建命令,这通常需要使用到命令捕获相关的技术。这是本文所探究的内容。

主要探究在 Windows 和 Linux 中,涉及到 C/C++ 和 Java 的编译捕获的场景。其他非编译的语言,不需要捕获,其他可能需要编译的,也类似。

1. 主要的已知编译命令捕获框架及工具

这部分罗列一些主要的已知编译命令捕获的框架或者工具,如果觉得有价值,可以参考使用。

  • strace/ptrace

适用于 linux,strace/ptrace 是 linux 原生提供的接口和命令,可以捕获所有的命令。目前已知有多款工具都是基于 strace/ptrace 实现。

因为是 linux 原生提供的接口,所以应该也不涉及什么 license 的问题,我觉得。

  • bear

bear 可以直接捕获并生成 clang 的 compile_commands.json,基于 linux 的 LD_PRELOAD 实现,因此也是只适用于 linux。

协议不是很友好,没办法直接用。

  • compiledb

专门用于 make 类型的构建任务,有点儿像是应用 make 的假编动作。因此可以用在 windows 上面,但是应用也有点儿受限。

协议不是很友好,没办法直接用。

  • msbuild-database[1]

可以用于使用 msbuild 构建的所有的任务,因为 msbuild 是 visual studio 内置的一个构建工具,因此只要是 visual studio 开发的任务,都可以使用该工具捕获构建命令。

该版本是在原生工具的基础上做了修改的,支持链接命令的获取,还是很值得使用的。

协议友好,就是需要依赖特定的 .net 版本,有点儿烦人,在对外交付的时候,建议做好封装。

  • CodeChecker

在 CodeChecker 中,也默认支持了一个编译命令捕获的工具,该工具和 bear 实现机制完全一致,但是协议很友好。如果是想自己实现,建议抛弃 bear,选用 CodeChecker。

  • clang-power-tools[2]

可以读取 visual studio 配置中的信息,直接生成 clang 的编译数据库。

  • 构建工具本身能力

比如 cmake、bazel、ninja 等,可以直接导出 clang 的编译数据库,也算是性能提升的途径,但是并不完善,导出来的数据,有时候有问题。

2. 编译命令捕获相关技术栈

下面,从个人工作经验角度,给出一个相对比较完整的,自己实现一款 SAST 工具的编译捕获实现技术栈:


图 1 C/C++编译捕获命令技术栈


  • 基于 hook 的方式捕获编译命令(首选)

在 linux 中,可以基于 LD_PRELOAD 捕获命令,在 windows 中,可以基于 Detours[3] 等 Microsoft 开源的 hook 工具捕获命令。

当前典型的商用工具,都是基于该方法实现的,比如 Coverity。该方式的主要优点:

(1) 实现简单

(2) 捕获准确,能够完整地体现用户的构建过程

(3) 使用方便

当然,该方式有一些局限,这里列出一部分:

(1) 沙箱、跨进程、通过拉起 docker 构建等方式无法支持;

(2) 必须完整构建,如果不执行 clean 动作,有可能无法捕获到完整命令。

如果一定要说有什么缺点,那就是可能有点儿慢,如果用户构建需要两个小时,那就需要等两个小时了。

  • 基于构建工具原生能力(补充)

基于 cmake、ninja、bazel 等直接导出 clang 编译数据库,虽然有一些信息缺失或者数据错误,但是挡不住快。

  • 其他不推荐使用的有点儿用的方法

比如:

(1) 从构建日志中提取编译命令,比如一些构建任务,构建时会打印编译命令;

(2) 从配置文件中提取编译命令,比如从 visual studio 的 sln、vcproj 等配置中获取。


参考

[1] https://github.com/UnitTestBot/msbuild-database

[2] https://github.com/Caphyon/clang-power-tools/tree/master

[3] https://github.com/microsoft/Detours


发布于: 刚刚阅读数: 5
用户头像

maijun

关注

还未添加个人签名 2019-09-20 加入

关注SAST工具开发、应用,DevSecOps、研发效能等

评论

发布
暂无评论
C/C++编译命令捕获机制及实现_编译命令捕获_maijun_InfoQ写作社区