【问题标题】:Return value corrupt when C++11 application uses non-C++11 library当 C++11 应用程序使用非 C++11 库时,返回值损坏
【发布时间】:2012-12-01 05:06:07
【问题描述】:

我有一个在没有 C++11 标志 (-std=c++11) 的情况下编译的库和一个链接到使用 -std=c++11 构建的库的应用程序。它调用库中的一个函数,然后程序在库中崩溃得更深。我发现发生崩溃的函数(它只是一个返回类中的指针的简单函数)的反汇编在调用堆栈源自该程序时与库的测试程序不同,后者也是'不是用 C++11 标志构建的。

操作系统是 OS X Mountain Lion,编译器是 Clang++。

为什么 C++11 应用程序和非 C++11 库之间没有能力,以及当不同的生成代码在库中并且应该相同时,何时生成反汇编?

两种不同的反汇编方式:

TestApplication`Core::GetPointer() const at System.h:xxx:
0x100009690:  pushq  %rbp
0x100009691:  movq   %rsp, %rbp
0x100009694:  movq   %rdi, -8(%rbp)
0x100009698:  movq   -8(%rbp), %rdi
0x10000969c:  movq   64(%rdi), %rax  ;<-------Difference
0x1000096a0:  popq   %rbp
0x1000096a1:  ret    

Lib1Prototype`Core::GetPointer() const at System.h:xxx:
0x100019c10:  pushq  %rbp
0x100019c11:  movq   %rsp, %rbp
0x100019c14:  movq   %rdi, -8(%rbp)
0x100019c18:  movq   -8(%rbp), %rdi
0x100019c1c:  movq   40(%rdi), %rax  ;<------Difference
0x100019c20:  popq   %rbp
0x100019c21:  ret    

【问题讨论】:

  • 那么,该库是否在其接口中公开了标准库的任何部分?有C接口吗?
  • 这是一个非常大的库,有一个很大的接口,所以我没有审查每个函数签名,但它似乎确实避免在其公共接口中暴露标准库,但它肯定在内部使用它(标题包含私有矢量和地图)。它的接口是C++。

标签: c++ macos c++11 shared-libraries clang


【解决方案1】:

在OS X使用的x86-64 ABI中,函数的第一个参数在%rdi中传递,函数的返回值在%rax中传递。*所以这个函数接受一个指向某个数据结构的指针,并返回从偏移量 64 或 40 开始包含的 64 位值,具体取决于函数的编译方式。

因此您需要查看定义该数据结构的头文件。它根据您是否编译为 C++11 来定义不同的数据结构。也许有一些显而易见的东西,比如你知道定义不同的#ifdef。或者也许有一个成员的类型定义不同。如果您无法弄清楚,请编辑您的问题并粘贴(通过指针)传递给Core::GetPointer 函数的数据结构的定义。

【讨论】:

  • 在此类的声明中没有#ifdef 检查语言版本,但有一个使用std::vector 的私有成员变量。语言版本之间链接的标准 C++ 库会有所不同,所以这可能是原因吗?
  • 这当然是可能的。您可以检查 &lt;vector&gt; 头文件以尝试找出它...或者只记录 sizeof 类/结构的每个成员,以每种方式编译,以查看哪个成员具有不同的大小。
  • 原来是 std::map (被 Core 继承的一个类使用)。它的大小有 24 个字节的差异。
  • @akai :欢迎来到 C++ 和二进制接口的世界。 ;-](提示:切勿混搭。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-15
  • 1970-01-01
  • 2014-06-21
  • 2017-10-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多