检测与GCC的ABI兼容性问题

时间:2012-09-27 20:08:00

标签: debugging gcc g++ glibc abi

我最近花了相当多的时间来追踪一个问题,原因是用-D_GLIBCXX_DEBUG编译了一个库(告诉libstdc ++使用带有额外检查的标准库的调试版本)但是没有编译客户端程序。这导致了ABI兼容性问题。

有什么方法可以通过GCC自动检测这样的问题吗? Visual Studio提供了detect_mismatch pragma我认为可以用于此目的,但我不知道任何GCC等价物。 GCC通过嵌入符号名称(例如GLIBCXX_3.4.9)来做一些事情,我可以想象如果相应的符号(例如mylib_debug_stl)不存在则由于未定义的符号而导致链接错误的方案,但是我能想到的唯一方法是使用使用这个符号真的很笨拙。

或者,其他人如何避免这个问题?将库的已检查版本构建为不同的名称或类似名称?

2 个答案:

答案 0 :(得分:4)

  

有什么方法可以通过GCC自动检测这样的问题吗?

只有链接器可以检测您是否链接了不兼容的代码,而不是编译器。

备用链接器gold可以检测--detect-odr-violations选项的一些问题。

  

或者,其他人如何避免这个问题?将库的已检查版本构建为不同的名称或类似名称?

我只是确保在我想使用调试模式时重建所有内容,我不认为我曾经想要保留一个使用调试模式构建的库。它用于调试,而不是正常使用。

无论如何我很少使用-D_GLIBCXX_DEBUG,我经常会这样做:

#if 0
# include <debug/vector>
namespace my_class_stl = __gnu_debug;
#else
#include <vector>
namespace my_class_stl = std;
#endif

struct my_class
{
  typedef my_class_stl::vector<int> container;
  typedef container::iterator iterator;
  // ...
};

然后,当我想为该特定类使用调试模式向量时,我更改了预处理器条件,而不会影响程序中的每个容器。由于更改涉及写入文件(因此更新其时间戳),依赖于该标头的任何内容都将由make重建,并且有两种不同的类型,std::vector<int>__gnu_debug::vector<int>,它们具有不同的符号,不能被链接器混淆。

仅定义_GLIBCXX_DEBUG不会导致重建所有依赖项,并且会以全局方式静默更改std::vector的定义,而不是将特定容器更改为具有不同名称的其他类型{{1 }}

答案 1 :(得分:0)

  

原因是使用-D_GLIBCXX_DEBUG(告诉libstdc ++使用带有额外检查的标准库的调试版本)编译库,但是没有编译客户端程序。

支持此类配置的显式 libsdc++调试模式设计目标,我有点怀疑这是您问题的实际原因。< / p>

重建没有-D_GLIBCXX_DEBUG的库后问题可能已经消失,但这并不能证明ABI不兼容是根本原因。