4

我使用 g++ 4.2.3 版在同一个 GNU/Linux 服务器上编译了 2 个不同的二进制文件。

第一个使用:

GLIBC_2.0
GLIBC_2.2
GLIBC_2.1
GLIBCXX_3.4
GLIBC_2.1.3

第二个使用:

GLIBC_2.0
GLIBC_2.2
GLIBC_2.1
GLIBCXX_3.4.9
GLIBCXX_3.4
GLIBC_2.1.3

为什么第二个二进制文件使用仅在 libstdc++.so.6.0.9 上可用而不在 libstdc++.so.6.0.8 上可用的 GLIBCXX_3.4.9

g++ 生成的需要 ABI 中断并强制系统具有 GLIBCXX_3.4.9 的新功能是什么?

有没有办法禁用这个新功能而不需要 GLIBCXX_3.4.9?

4

3 回答 3

8

要找出您的二进制文件实际上依赖于列出的 GLIBCXX_3.4.9 符号中的哪个,请执行以下操作:

readelf -s ./a.out | grep 'GLIBCXX_3\.4\.9' | c++filt

一旦知道要查找哪些符号,就可以追溯到需要它们的对象:

nm -A *.o | grep _ZN<whatever>

最后,要将其与源代码联系起来,您可以执行以下操作:

objdump -dS foo.o

并查看哪个代码引用了 3.4.9 符号。

于 2009-01-08T04:58:55.327 回答
3

既然你要求它,这里有至少 ABI 版本 3.4.9 的符号:

GLIBCXX_3.4.9 {

    _ZNSt6__norm15_List_node_base4hook*;
    _ZNSt6__norm15_List_node_base4swap*;
    _ZNSt6__norm15_List_node_base6unhookEv;
    _ZNSt6__norm15_List_node_base7reverseEv;
    _ZNSt6__norm15_List_node_base8transfer*;

    _ZNSo9_M_insertI[^g]*;
    _ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertI[^g]*;
    _ZNSi10_M_extractI[^g]*;
    _ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractI[^g]*;

    _ZSt21__copy_streambufs_eofI[cw]St11char_traitsI[cw]EE[il]PSt15basic_streambuf*;

    _ZSt16__ostream_insert*;

    _ZN11__gnu_debug19_Safe_sequence_base12_M_get_mutexEv;
    _ZN11__gnu_debug19_Safe_iterator_base16_M_attach_singleEPNS_19_Safe_sequence_baseEb;
    _ZN11__gnu_debug19_Safe_iterator_base16_M_detach_singleEv;
    _ZN11__gnu_debug19_Safe_iterator_base12_M_get_mutexEv;

    _ZNKSt9bad_alloc4whatEv;
    _ZNKSt8bad_cast4whatEv;
    _ZNKSt10bad_typeid4whatEv;
    _ZNKSt13bad_exception4whatEv;

} GLIBCXX_3.4.8;

通过 c++filt运行文件libstdc++-v3/config/abi/post/i386-linux-gnu/baseline_symbols.txt,查找 GLIBCXX_3.4.9 以理解这些名称(它们看起来只是通配符)。我没有这样做,因为这些名字变得很长而且嵌套。后来的版本主要包括 c++1x 的东西。请参阅上述文件libstdc++-v3/config/abi/pre/gnu.ver在此处阅读有关 VERSION 链接描述文件命令的信息。

于 2009-01-07T19:15:09.000 回答
0

那么第一个问题是您是如何生成上述列表的。
有人会假设编译器是确定性的,因此以相同的方式链接二进制文件。

我想我因为没有直接回答问题而被打分,但评论会很好。但我仍然认为您没有提供正确的信息,很高兴看到显示您的问题的命令输出。

假设您使用 ldd:
您将得到如下所示的输出:

lib<X>.so.<ver>  =>  /usr/lib/lib<X>.so.<verM>  (<Addr>)

但这不是故事的结局。
尝试对文件执行 ls 可能是符号链接

> ls /usr/lilb/lib<X>.so.<verM>
lrwxrwxrwx 1 root root    <Date>  /usr/lib/lib<X>.so.<verM>  -> lib<X>.so.<verM>.<verm>.<verp>
于 2009-01-07T18:24:44.843 回答