用于检测C++ ABI变化的静态分析工具

26

破坏带有C++接口的DSO/共享库的二进制后向兼容性并不困难。但是,是否有一种静态分析工具可以在给定早期DSO状态和当前状态(以及可能的DSO)的两个不同的头文件集时,帮助检测此类ABI中断呢?欢迎提供免费和商业产品建议。

如果它还能警告关于不良实践的问题,例如在DSO接口中的内联函数和默认函数参数,那就太好了。


2
你为什么认为内联函数和默认参数是不好的实践? - anon
另外,我不确定您是否理解ABI的含义 - 我看不出它与头文件有什么关系。理想情况下,如果发生ABI不兼容性,链接器将会发现它。 - anon
2
也许我没有表明我正在构建一个DSO,如果库接口有内联函数,则会将其编译到DSO的客户端中。因此,更改内联函数不会影响应用程序的功能。默认函数参数也是如此。 - okun
DSO?也许这就是你所做的事情不清晰的原因。平台? - jmucchiello
1
动态共享对象(DSO),也称为共享库。平台是Linux和商业Unix系统。 - okun
6个回答

21

abi-compliance-checker - 一款用于检查共享 C/C++ 库(DSO)的向后二进制/源代码级别兼容性的工具:

这是一款检查 C/C++ 库向后二进制和源码级别兼容性的工具。该工具会检查旧版本和新版本的头文件和共享库,并分析 API 和 ABI(ABI=API+编译器 ABI)的更改,这些更改可能会破坏二进制和/或源码的兼容性:调用堆栈的更改、v-table 的更改、删除符号、重命名字段等。

enter image description here

icheck - C 接口 ABI/API 检查工具:

这是一款用于静态检查 C 接口的 API 和 ABI 更改的工具。它可以检测到可能导致 ABI 更改的所有类型声明更改,以及大多数 API 更改。 icheck 旨在与库一起使用,作为防止 ABI 漂移的方法。

shlib-compat - 具有符号版本控制的共享库 ABI 兼容性检查工具:

shlib-compat 使用 DWARF 调试符号来重建和比较导出符号的定义,包括函数参数和结构类型。

此外,您可能会对 linux upstream trackerlinux abi tracker 服务感兴趣。它们都是由 abi-compliance-checker 工具提供支持。


15

1
是的,我知道该做什么和不该做什么,这也是我询问是否有任何工具可以自动执行明显检查的动机。ABI兼容性检查器看起来很有帮助。我会试一试。干杯! - okun

1

我记得在工作中,他们使用GCC XML来测试二进制兼容性。基本上它所做的就是生成编译器对象树的xml表示。理论上,如果xml是等效的,那么二进制兼容性就已经得到了维护。


0
唯一安全的方法是使用 C 接口导出您的库。C++ 库只与您用于编译它的一个编译器兼容。

客户非常清楚编译器的要求。DSO是一个室内项目,公司各个部门都有广泛的客户群,但获取完全相同的编译器版本并不是问题。 - okun

0
我们的C++智能差异工具可以比较两个源文件,并以语言结构(标识符、表达式、语句等)和合理的编辑操作(插入、删除、移动、复制、替换标识符等)报告它们之间的差异。
虽然它不能直接回答ABI问题,但提供的信息可能非常有用。例如,在另一个答案中讨论的一个例子是从struct {a,b}更改为struct {b,a}的返回类型。SmartDifferencer会报告a已被移动。(注意:普通的diff工具会报告包含结构定义的行已更改,因此您可以获得相同的信息,但SmartDifference还会忽略空格/布局和注释的更改,从而产生更少的概念噪音)。

这两个工具都不会报告typedef定义的更改,因为它在另一个头文件中。但是假设人们会比较涉及的所有头文件。如果您不想手动执行此操作,则使用的任何工具必须包含基本上完整的C++解析器、名称解析器,并且必须比较等效的声明。另一位发帖者建议几乎就是这个答案:比较GCCXML输出以确定等效性。我不确定实际操作起来有多容易;它不能仅仅是“文件的XML顺序相同吗?”。


-1

ABI - 应用程序二进制接口是指编译器将源代码转换为机器可识别指令的方式。同一行源代码可以被翻译成不同的字节流,在最终的程序中。

在源代码上运行的静态分析器无法预测编译器将如何翻译它。这个决定是在编译器编码或设置中做出的。因此,我认为在这种情况下,静态分析器对你没有帮助。


1
一个静态分析工具可以检测到函数返回类型的更改,向现有成员函数添加虚拟关键字,更改函数参数的类型,向可实例化为堆栈的类添加成员。所有这些都会破坏二进制向后兼容性。因此,我不同意。静态分析器可以帮助检测ABI中断。 - okun
我必须表示不同意:例如,静态分析器将检测到一个函数返回值是一个结构体,比如说有整数元素a、b。在检查源代码时,静态分析器不可能知道编译器是否会将结构体在内存中设置为{a,b}或{b,a},它们仍然是相同的结构体但具有不同的ABI方案。 - Alon
1
认为OP指的是给这个理论工具一个旧版本和新版本的相同头文件,然后该工具会判断新版本中的更改是否意味着使用旧版本编译的库不再适用于新头文件。 - Jim Buck
1
你是正确的,静态分析工具没有足够的信息来检测所有的错误,但它可以检测到返回值是否已经被改变,例如从char类型变为int类型。我更喜欢在编译时就发现这些明显的错误,而不是之后再去处理。 - okun
我不知道是否有这样的工具,但它听起来对于库文件/动态链接库的编写者来说将会非常有用。如果这个工具不存在,也许有人可以抓住商机 :) - Jim Buck
1
如果你的ABI发生了变化,你必须重新编译应用程序。如果头文件没有改变,重新编译的应用程序将是相同的。因此,如果你的ABI出现问题,你的头文件肯定发生了变化。 - Nicolás

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接