首页 文章

std :: regex和双ABI

提问于
浏览
6

今天我发现了一个有趣的双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正则表达式编译器有一些存储 std::string 的内部静态数据,当两个ABI不兼容的代码片段试图使用该数据时,它会得到有关布局的相互矛盾的想法 . std::string 个对象 .

所以我的问题是:

  • 这个问题有解决方法吗?

  • 这应该被视为libstdc中的错误吗?

这个问题在g / libstdc的几个版本中是可重现的(我尝试了一些从5.4到7.1) . libc不会发生这种情况 .

1 回答

  • 4

    问题源于libstdc为何具有dual ABI的原因 . 从这两个重要的陈述:(1)它是专门为了符合新的第11个标准而引入的,以及 string (以及与此讨论无关的其他方面)如何起作用; (2) _GLIBCXX_USE_CXX11_ABI 独立于方言工作,并用于一起编译C 03和C 11 .

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

    那会有用吗?取决于 regex 如何使用字符串,如果它依赖于新的实现(例如禁止写入时复制),则不,否则为是 . 怎么会发生什么?任何东西 .

    在它的底部,你不应该在任何使用post-c -03方言的新代码(即c -11,14,17,...)上使用 _GLIBCXX_USE_CXX11_ABI=0 ,因为它引入了与新保证不兼容的实现在标准对象上,尤其是 std::string .

    我可以使用 _GLIBCXX_USE_CXX11_ABI=0 与std> = c -11吗? GCC开发人员注意到您可以使用旧的ABI运行新的东西,它有可能使用旧的共享库运行新功能 . 然而,这可能不是一个好主意,也因为代码是新标准,但标准库不符合此标准,可能会在以后发生严重后果 . 你的问题就是一个例子 . 你可以通过混合两个ABI,在这里,我们是不工作 .

    如果您调用某些.so库中定义的 foo(std::string const&) ,使用旧的ABI编译,则 _GLIBCXX_USE_CXX11_ABI=0 确实可用 . 然后在新的源文件中,您希望使用旧的ABI编译此源代码 . 但是你会用新的ABI保留所有其他来源 .

    这个问题在g / libstdc的几个版本中是可重现的(我尝试了一些从5.4到7.1) . libc不会发生这种情况 .

    libc++ 没有这种二元性,即单一 string 实现 .

    我没有给出这个例外的来源或原因 . 我只能猜测有一些与 regexstringlocale 相关的共享全局资源在ABI之间没有明确区分 . 并且不同的ABI以不同的方式工作,导致任何事情,例如,异常,段错误,任何意外行为 . 恕我直言,我更喜欢坚持上面提到的规则,这些规则最接近 _GLIBCXX_USE_CXX11_ABI 和双ABI的意图 .

相关问题