4

g++ バージョン 4.2.3 を使用して、同じ GNU/Linux サーバーで 2 つの異なるバイナリをコンパイルしました。

最初のものは使用します:

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

2番目のものは次を使用します:

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

2 番目のバイナリが libstdc++.so.6.0.9 でのみ使用可能で、libstdc++.so.6.0.8 では使用できない GLIBCXX_3.4.9 を使用する理由

ABI ブレークを必要とし、システムに GLIBCXX_3.4.9 を強制する、g++ によって生成される新しい機能は何ですか?

この新機能を無効にして 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;

ファイルlibstdc++-v3/config/abi/post/i386-linux-gnu/baseline_symbols.txtを c++filt で実行し、GLIBCXX_3.4.9 を grep して、これらの名前を理解します (ワイルドカードのみのように見えます)。これらの名前は非常に長くネストされているため、私はそれをしませんでした。それ以降のバージョンには、ほとんどの場合 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 に答える