【问题标题】:Static analysis tool to detect ABI breaks in C++ [closed]用于检测 C++ 中 ABI 中断的静态分析工具 [关闭]
【发布时间】:2010-12-30 12:09:39
【问题描述】:

破坏具有 C++ 接口的 DSO/共享库的二进制向后兼容性并不难。也就是说,是否有一个静态分析工具可以帮助检测这种 ABI 中断,如果它有两组不同的头文件:DSO 的早期状态和当前状态的那些(也许还有 DSO)?欢迎提供免费和商业产品建议。

如果它还可以警告不良做法,例如DSO接口中的内联函数和默认函数参数,那就太好了。

【问题讨论】:

  • 是什么让你认为内联函数和默认参数是不好的做法?
  • 另外,我不确定您是否理解 ABI 的含义 - 我看不出它与头文件有什么关系。理想情况下,如果您确实遇到 ABI 不兼容问题,链接器会发现它。
  • 也许不是很清楚我正在构建一个 DSO。如果库接口有内联函数,则将其编译到 DSO 的客户端中。因此更改内联函数不会影响应用程序的功能。默认函数参数也是如此。
  • DSO?也许这就是为什么你在做什么不清楚。平台?
  • 动态共享对象 (DSO) 又名共享库。这些平台是 Linux 和商业平台。

标签: c++ shared-libraries static-analysis backwards-compatibility


【解决方案1】:

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

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

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 工具提供支持。

【讨论】:

    【解决方案2】:

    我假设您熟悉本教程:Binary Compatibility Issues with C++,如果不是阅读它!

    我听说过这个工具: http://ispras.linuxbase.org/index.php/ABI_compliance_checker,但从未测试或使用过,所以没有意见。

    您也可能对此感兴趣:Creating Library with backward compatible ABI that uses Boost

    【讨论】:

    • 是的,我知道该做什么和不该做什么,这也是我询问是否有任何工具可以自动执行明显检查的动机。 ABI 合规性检查器看起来确实很有帮助。我会试一试。干杯!
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 客户非常了解编译器的要求。 DSO 是一个室内项目,在整个公司拥有广泛的客户,但获得相同的编译器版本是没有问题的。
      【解决方案5】:

      我们的C++ Smart Differencer 工具比较两个源文件并报告语言结构(标识符、表达式、语句等)和合理的编辑操作(插入、删除、移动、复制、替换标识符等)方面的差异。 .).

      它不会直接回答 ABI 问题,但它提供的信息可能会很有帮助。另一个答案中讨论的一个示例是从 struct {a,b}struct {b,a} 的 change-of-return-type。 SmartDifferencer 会报告 a 已移动。 (注意:常规 diff 工具会报告包含结构定义的行已更改,因此您会获得相同的信息,但 SmartDifference 也会忽略空格/布局和 cmets 的更改,从而产生更少的概念噪音)。

      这些工具都不会报告 typedef 定义的变化,它在另一个头文件中。但随后大概会比较所有涉及的头文件。如果您不想手动执行此操作,则使用的任何工具都必须包含完整的 C++ 解析器、名称解析器,并且必须比较声明的等效性。另一张海报几乎提出了这个答案:比较 GCCXML 输出的等效性。我不确定这在实践中有多容易。它不能只是“文件的顺序是相同的 XML 吗?”。

      【讨论】:

        【解决方案6】:

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

        在源代码上运行的静态分析器将无法预测编译器将如何翻译它。该决定是在编译器编码或设置中做出的。所以我不相信在这种情况下静态分析器会对你有所帮助。

        【讨论】:

        • 静态分析工具可以检测改变函数的返回类型、向现有成员函数添加虚拟关键字、改变函数参数的类型、向可实例化到堆栈的类添加成员。所有这些都破坏了二进制的向后兼容性。所以,我不同意。静态分析器可以帮助检测 ABI 中断。
        • 我不同意:例如,一个静态分析器会检测到一个函数返回值是一个结构,比如带有整数元素 a,b。在检查源代码时,静态分析器无法知道编译器是否会将内存中的结构设置为 {a , b} 或 {b, a} ,它仍然是相同的结构但不同的 ABI 方案
        • 认为 OP指的是给这个理论工具一个相同头文件的旧版本和新版本,并且该工具会说明新版本中的更改是否会意味着用旧版本编译的库不再适用于新的头文件。
        • 你是对的,静态分析工具没有足够的信息来检测所有中断,但它可以检测到,如果返回值已更改,例如从 char 到 int。而且我更喜欢在编译时而不是以后发现这些明显的错误。
        • 如果您的 ABI 发生变化,您必须重新编译应用程序。如果标头没有更改,则重新编译的应用程序将是相同的。因此,如果您的 ABI 中断,您的标题肯定会改变。
        猜你喜欢
        • 1970-01-01
        • 2023-03-14
        • 1970-01-01
        • 2010-11-13
        • 2010-09-10
        • 1970-01-01
        • 1970-01-01
        • 2010-09-13
        • 1970-01-01
        相关资源
        最近更新 更多