静态初始化期间将 gcc 构建的 Boost 链接到英特尔 C++ 编译程序时出现 Segfault

Segfault during static initialization when linking gcc-built Boost into an Intel C++-compiled program

本文关键字:C++ 英特尔 编译程序 Segfault 链接 Boost 初始化 gcc 构建 静态      更新时间:2023-10-16

我有一个安装了最新SVN版本的Boost C++库的Ubuntu 13.04系统。Boost 安装是使用系统的本机gcc版本 v4.7.3 构建的。我广泛使用 Boost,当我使用 gcc 进行编译时,它运行良好;我已经使用了很多,包括Boost.Thread(我将在下面详细讨论),没有任何问题。

如果我尝试使用与已安装的 Boost 库链接的英特尔C++编译器(我个人在 v13.x 系列中使用了几个不同版本)构建程序,则会出现问题。当我这样做时,我在程序启动后立即出现分段错误;它似乎发生在 Boost.Thread 库的静态初始化期间。下面是一个简单的示例程序:

#include <boost/version.hpp>
#include <boost/thread.hpp>
int main()
{
    boost::this_thread::sleep(boost::posix_time::seconds(1));
}

我使用英特尔C++编译它:

icpc test.cc -lboost_thread -lboost_system -I/path/to/boost/inc/dir -L/path/to/boost/lib/dir

正如我所说,当我运行生成的程序时,我几乎立即出现段错误。通过gdb,从段错误点开始的堆栈跟踪如下:

#0  0x00007ffff79b6351 in boost::exception_ptr boost::exception_detail::get_static_exception_object<boost::exception_detail::bad_exception_>() () from ./libboost_thread.so.1.55.0
#1  0x00007ffff79b02e1 in _GLOBAL__sub_I_thread.cpp () from ./libboost_thread.so.1.55.0
#2  0x00007ffff7de9876 in call_init (l=l@entry=0x7ffff7ff9a10, argc=argc@entry=1, 
    argv=argv@entry=0x7fffffffe0b8, env=env@entry=0x7fffffffe0c8) at dl-init.c:84
#3  0x00007ffff7de9930 in call_init (env=<optimized out>, argv=<optimized out>, 
    argc=<optimized out>, l=0x7ffff7ff9a10) at dl-init.c:55
#4  _dl_init (main_map=0x7ffff7ffe268, argc=1, argv=0x7fffffffe0b8, env=0x7fffffffe0c8)
    at dl-init.c:133
#5  0x00007ffff7ddb68a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#6  0x0000000000000001 in ?? ()
#7  0x00007fffffffe391 in ?? ()
#8  0x0000000000000000 in ?? ()

不是很有启发性,但它显然在libboost_thread.so初始化期间正在消亡。如果我重建包含调试符号的 Boost,那么我会得到稍微好一点的图片:

#0  shared_count (r=..., this=0x7ffff7bbc5f8 <boost::exception_ptr boost::exception_detail::get_static_exception_object<boost::exception_detail::bad_exception_>()::ep+8>)
    at ./boost/smart_ptr/shared_ptr.hpp:328
#1  shared_ptr (this=0x7ffff7bbc5f0 <boost::exception_ptr boost::exception_detail::get_static_exception_object<boost::exception_detail::bad_exception_>()::ep>) at ./boost/smart_ptr/shared_ptr.hpp:328
#2  exception_ptr (ptr=..., this=0x7ffff7bbc5f0 <boost::exception_ptr boost::exception_detail::get_static_exception_object<boost::exception_detail::bad_exception_>()::ep>)
    at ./boost/exception/detail/exception_ptr.hpp:53
#3  boost::exception_detail::get_static_exception_object<boost::exception_detail::bad_exception_> () at ./boost/exception/detail/exception_ptr.hpp:130
#4  0x00007ffff79b02e1 in __static_initialization_and_destruction_0 (__initialize_p=<optimized out>, __priority=<optimized out>) at ./boost/exception/detail/exception_ptr.hpp:143
#5  _GLOBAL__sub_I_thread.cpp(void) () at libs/thread/src/pthread/thread.cpp:767
#6  0x00007ffff7de9876 in call_init (l=l@entry=0x7ffff7ff9a10, argc=argc@entry=1, argv=argv@entry=0x7fffffffe0b8, env=env@entry=0x7fffffffe0c8) at dl-init.c:84
#7  0x00007ffff7de9930 in call_init (env=<optimized out>, argv=<optimized out>, argc=<optimized out>, l=0x7ffff7ff9a10) at dl-init.c:55
#8  _dl_init (main_map=0x7ffff7ffe268, argc=1, argv=0x7fffffffe0b8, env=0x7fffffffe0c8) at dl-init.c:133
#9  0x00007ffff7ddb68a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#10 0x0000000000000001 in ?? ()
#11 0x00007fffffffe391 in ?? ()
#12 0x0000000000000000 in ?? ()

我不清楚是什么静态/全局对象导致问题发生,所以我不确定如何继续。我在 v13.x 系列中使用了许多 Boost 版本和几个不同版本的英特尔 C++ 编译器复制了此行为,这是我目前唯一可以访问的版本。我已经尝试了所有编译器排列(即我已经用gccicpc构建了 Boost,并且我也用两者构建了我的测试应用程序);唯一失败的排列是使用 gcc 构建 Boost 而我的测试应用程序是使用 icpc 构建的。在所有其他情况下,测试应用程序都会成功运行。

话虽如此,您可能会得到显而易见的答案:

  • 为什么不直接使用icpc重建 Boost 并结束一天呢?考虑到我的实验,这种方法似乎很有效,但我有客户喜欢使用icpc来构建我的软件。这些客户可能安装了Linux发行版提供的Boost软件包;他们对用于生成该包的构建环境没有任何控制权(而且,无论如何,它很可能是使用 gcc 编译的)。因此,如果可以支持这种混合编译器配置,那将是最佳的。

有没有人对我如何解决这个静态初始化问题有任何建议?

这是一个

很长的镜头,但是...如果您的PATH中有与用于构建 Boost 库的g++不同的,请将其删除或-gxx-name /usr/bin/g++传递给 icpc 。(英特尔编译器会根据它认为您正在使用的 GCC 版本进行自我调整。 -gxx-name允许您强制解决问题。

好吧,这可能没有帮助。

在英特尔作曲家 XE 2013 SP1(又名编译器版本 14.0.0)之前不支持 Ubuntu 13.04。请参阅发行说明的"系统要求"部分,并将其与上一版 13.x 版本的同一部分进行比较。

英特尔绝对致力于与 GCC 的链路兼容性。如果可以在全新安装受支持的 Linux 版本时重现此问题,则应该能够提交支持票证并修复它。