std :: regex和双重ABI

时间:2018-07-17 13:14:46

标签: c++ c++11 g++ libstdc++ abi

今天,我发现了一个有趣的案例:双重libstdc ++ ABI影响库的兼容性。

长话短说,我有两个内部都使用std :: regex的库。一种是使用CXX11 ABI构建的,另一种则不是。当将这两个库链接到一个可执行文件中时,它会在启动时崩溃(在输入main之前)。

这些库是不相关的,并且不会公开提及任何std::类型的接口。我认为这样的库应该不受双重ABI问题的影响。显然不是!

此问题可以通过以下方式轻松重现:

// file.cc
#include <regex>
static std::regex foo("(a|b)");

// main.cc
int main() {}

// build.sh
g++ -o new.o file.cc
g++ -o old.o file.cc -D_GLIBCXX_USE_CXX11_ABI=0 
g++ -o main main.cc new.o old.o
./main

输出为:

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted (core dumped)

无论我做什么,问题仍然存在。 file.cc可以做成两个单独的源文件,编译成单独的共享库,两个std::regex对象可以有不同的名称,它们可以做成全局,静态或自动的(一个将需要调用相应的函数从main开始)。这些都无济于事。

显然(这是我的简短调查得出的结果),libstdc ++ regex编译器具有某种内部静态数据,该数据存储std::string,并且当两个不兼容ABI的代码段尝试使用该数据时,对std::string对象的布局有相互矛盾的想法。

所以我的问题是:

  • 是否有解决此问题的方法?
  • 这应该被视为libstdc ++中的错误吗?

该问题在g ++ / libstdc ++的多个版本中都可以重现(我尝试从5.4到7.1中的几个)。 libc ++不会发生这种情况。

1 个答案:

答案 0 :(得分:4)

问题源于libstdc ++具有dual ABI的原因。从这两个重要的陈述中可以得出:(1)在string(以及与该讨论无关的其他内容)的工作方式方面,为了符合新的第11标准而专门引入该标准; (2)_GLIBCXX_USE_CXX11_ABI独立于方言而工作,用于一起编译C ++ 03和C ++ 11。

regex模块在​​第11个标准中引入,并在内部使用字符串。因此,您可以使用basic_regex构建c ++-11(或更高版本)模板_GLIBCXX_USE_CXX11_ABI=0代码。这意味着您正在使用c ++-11 regex对象和c ++-11之前的字符串实现。

那行得通吗?根据{{​​1}}使用字符串的方式,如果它确实依赖于新的实现(例如,禁止写时复制),则为否,否则为是。会发生什么?一切。

最简单的说,您不应该在使用后c ++-03方言的任何新代码(即c ++-11,14,17,...)上使用regex,因为它引入了实现与标准对象(尤其是_GLIBCXX_USE_CXX11_ABI=0)上的新保证不兼容。

我可以将std::string与std> = c ++-11一起使用吗? GCC开发人员要小心,您可以使用旧的ABI运行新的东西,这可能会使新功能与旧的共享库一起运行而受益。但是,这可能不是一个好主意,因为代码是在新标准中,但是标准库不符合该标准,以后可能会出现问题。您的问题就是一个例子。您可以将两个ABI混合使用,到这里我们无法正常工作。

如果您调用

_GLIBCXX_USE_CXX11_ABI=0确实是有用的,例如,调用在某个.so库中定义的_GLIBCXX_USE_CXX11_ABI=0,该库是用旧的ABI编译的。然后,在新的源文件中,您想使用旧的ABI编译该源。但是您将使用新的ABI保留所有其他来源。

  

该问题在g ++ / libstdc ++的多个版本中都可以重现(我尝试从5.4到7.1中的几个)。 libc ++不会发生这种情况。

foo(std::string const&)不具有这种双重性,即单个libc++实现。

我没有给出明确的答案,此异常来自何处或为什么。我只能猜测,有一些与stringregexstring相关的共享全局资源在ABI之间没有明确区分。并且不同的ABI对其进行不同的处理会导致什么结果,例如异常,段故障,任何意外行为。恕我直言,我更喜欢遵循上面提到的规则,这些规则最能反映出locale和双重ABI的意图。