g++ に GLIBCXX_3.4.9 が含まれるのはなぜですか?
-
05-07-2019 - |
質問
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 でのみ利用可能な GLIBCXX_3.4.9 を使用する理由 ない libstdc++.so.6.0.8 内
ABI ブレークを必要とし、システムに GLIBCXX_3.4.9 を強制する g++ によって生成された新機能は何ですか?
GLIBCXX_3.4.9 を必要としないようにこの新機能を無効にする方法はありますか?
解決
リストされた 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 シンボルを参照しているかを確認します。
他のヒント
あなたがそれを求めたので、少なくとも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をgrepしてそれらの名前を理解します(ワイルドカードのみのように見えます)。それらの名前が非常に長くネストされるため、私はそれをしませんでした。それ以降のバージョンには、主にc ++ 1xのものが含まれています。上記については、ファイル libstdc ++-v3 / config / abi / pre / gnu.ver
を参照してください。 VERSIONリンカースクリプトコマンドについては、こちらをご覧ください。 。
最初の質問は、上記のリストをどのように生成したかです。
コンパイラーは決定論的であるため、同じ方法でバイナリーをリンクすると仮定します。
質問に直接答えないことでマークダウンされたと思いますが、コメントはいいでしょう。しかし、あなたはまだ正しい情報を提供していないと思うので、問題を示すコマンドの出力を見るといいでしょう。
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>