如何在C ++中检测API中断

时间:2015-10-05 20:39:25

标签: c++ static-analysis

如何在C ++中检测不兼容的API更改? (不是ABI,但API更改)

兼容性更改是指使用以下API无法破坏代码编译的内容:

  • 参数添加到带有默认参数的方法
  • 添加到班级的方法
  • 成员已添加到班级
  • 已添加课程
  • 成员或方法的顺序已更改
  • 评论/文档更改

不兼容的更改可能会破坏使用API​​的代码编译:

  • 删除了参数,(公共/受保护)方法,成员,类
  • 参数或成员的类型更改
  • 公开/受保护成员或方法的名称更改
  • 类从一个标题移到另一个标题

2 个答案:

答案 0 :(得分:3)

OP认为C ++解析可能是必要的,这是正确的。也可能是深刻的推理。

我认为提出问题的方法是,

对于现有应用程序中API的一组特定用途,是否更改了应用程序的API更改或中断?

如果您不限制自己使用特定的一组用途,那么对API的任何更改几乎都会改变其语义。否则,你为什么要制作它们(模数重构?)。如果您在应用程序中使用完整的API功能集,那么它的语义也必须以某种方式改变。

使用一组特定用途,可以确定API的哪些属性可能会影响特定用途,并确定它们是否确实如此。最终,您必须准确地解析原始代码 ,以确定特定的使用集和使用它们的上下文。您还必须确定现有应用程序所依赖的语义属性,包括旧API提供的属性。最后,您需要确定新API定义的属性,并验证仍然支持应用程序的需求。

通常,您需要一个关于程序属性的定理证明器来检查它。而且,虽然定理证明技术在过去50年中取得了显着进步,但AFAIK表示技术不够强大,无法采用一般任意的程序属性并证明它们,更不用说克服任意复杂程序的推理问题了。

考虑:

 // my application
 int x=0;
 int y=foo(x); // API ensures that fail...
 if (y>3) then fail(); // shouldn't happen 
 exit();

 // my legacy API
 int foo(int x) { return x+1; }

现在假设API已更改为:

 // my new API
 int foo(int x) { return x+2; }

应用程序仍能正常运行。 怎么样:

 // my new API
 int foo(int x) { return TuringMachine(x); }

我们如何证明TuringMachine(x)产生的值

现在,您可以限制要考虑的更改集 简单的“语法”操作,例如“移动方法”,“添加具有初始值的参数”等等。

您仍然需要解析原始程序和修改的API,并检查语法属性是否意味着不会损坏原始程序的语义属性。您可能需要控制和数据流分析,别名分析以担心指针等,并且该工具最多能够在没有发生任何变化时告知有限数量的情况。

我确信有关于这个主题的研究论文。在scholar.google.com上快速检查没有找到任何明显的内容。

答案 1 :(得分:3)

请参阅ABICC工具报告的"来源兼容性" 标签。此工具会检测到大多数提到的API更改和API中断。

使用该工具有两种方法。原始通过头文件分析和库调试信息([1])的新的通过分析。使用第二个。它更可靠,更简单。

您可以在此处找到一些报告示例:http://abi-laboratory.pro/tracker/

教程:https://sourceware.org/glibc/wiki/Testing/ABI_checker#Usage

enter image description here

enter image description here