繁体   English   中英

指定O2标志时,gcc链接到错误的GLIBCXX版本

[英]gcc links to wrong GLIBCXX version when O2 flag is specified

我有一个使用Makefile构建的共享库文件。 我遇到一个问题,在构建库之后,我会得到可怕的GLIBCXX_ not found链接器错误。

这种情况特别奇怪。 当我使用-g3标志进行编译时,没有得到该错误。 如果我使用-O2编译, -O2收到错误消息。

因此,当我使用-O2编译,并对编译的.so文件运行ldd ,我得到:

$ ldd MYLIB.so.1
./MYLIB.so.1: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./MYLIB.so.1)
        linux-vdso.so.1 =>  (0x00007fff21e8d000)
        libz.so.1 => /lib64/libz.so.1 (0x00002b2cd4c40000)
        libpng12.so.0 => /usr/lib64/libpng12.so.0 (0x00002b2cd4e54000)
        libjpeg.so.62 => /usr/lib64/libjpeg.so.62 (0x00002b2cd5079000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b2cd529b000)
        libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002b2cd54b7000)
        libm.so.6 => /lib64/libm.so.6 (0x00002b2cd57b8000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b2cd5a3b000)
        libc.so.6 => /lib64/libc.so.6 (0x00002b2cd5c49000)
        /lib64/ld-linux-x86-64.so.2 (0x0000003891400000)

所以在这里,出于某种原因, /usr/lib64/libstdc++.so.6正在寻找GLIBCXX_3.4.9 ,不存在中/usr/lib64/libstdc++.so.6 ,我们可以看到使用strings实用程序:

$ strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_FORCE_NEW

因此,为进一步研究此问题,我对已编译的.so文件运行nm ,并尝试查找正在寻找GLIBCXX_3.4.9符号

$ nm --demangle MYLIB.so.1 | grep GLIBCXX_3.4.9
  U std::ostream& std::ostream::_M_insert<unsigned long>(unsigned long)@@GLIBCXX_3.4.9
  U std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)@@GLIBCXX_3.4.9

好的,看起来某些标准C ++ ostream代码需要GLIBCXX_3.4.9。 好的...但是似乎只有这一个符号需要GLIBCXX_3.4.9。 其他所有内容均与GLIBCXX_3.4正确链接:

    $nm --demangle MYLIB.so.1 | grep GLIBCXX
      U std::string::find(char const*, unsigned long, unsigned long) const@@GLIBCXX_3.4
      U std::string::compare(char const*) const@@GLIBCXX_3.4
      U std::string::compare(std::string const&) const@@GLIBCXX_3.4
      U std::logic_error::what() const@@GLIBCXX_3.4
      U std::runtime_error::what() const@@GLIBCXX_3.4
      U std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::str() const@@GLIBCXX_3.4
      U std::basic_iostream<char, std::char_traits<char> >::~basic_iostream()@@GLIBCXX_3.4

... etc ...

那么,这可能是什么原因呢? 为什么一个特定的符号链接GLIBCXX_3.4.9,而其余的不链接? 更奇怪的是-这仅在我使用-O2编译时发生。

我对此感到困惑。 那么,为什么会发生这种情况呢? 链接程序/编译器链如何确定在其中找到特定符号的GLIBCXX版本?

这仅表示您正在使用比/usr/lib64/libstdc++.so库所属的更新的GCC进行编译,并且您没有在告诉动态链接器如何找到正确的libstdc ++。so。

对GLIBCXX_3.4.9的引用意味着您至少使用GCC 4.2.0进行编译,但是系统libstdc ++。so来自较旧的版本4.1.1或4.1.2。

在-O2处仅是一个问题这一事实并没有太大关系,如果使用较新的GCC进行编译,则需要使用其libstdc ++。so,句点。 看起来,除非您使用-O2进行编译,否则实际上并没有对较新的libstdc ++ ..的硬依赖性,但这只是偶然的机会,如果对代码进行任何细微更改以使它的优化略有不同,它可能会更改。

您需要阅读https://gcc.gnu.org/onlinedocs/libstdc++/faq.html#faq.how_to_set_pathshttps://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dynamic_or_shared.html#manual.intro。 using.linkage.dynamic

为什么一个特定的符号链接GLIBCXX_3.4.9,而其余的不链接?

因为在GCC 3.4和4.2之间其他符号不变,并且旧的libstdc ++。so中的符号版本与构建可执行文件时链接的符号相同。

未找到的符号是GCC 4.2中的新功能,因此为它提供了较新的符号版本,而在较旧的库中找不到。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM