O que faz o G ++ incluir glibcxx_3.4.9?
-
05-07-2019 - |
Pergunta
Compilei 2 binários diferentes no mesmo servidor GNU/Linux usando o G ++ versão 4.2.3.
O primeiro usa:
GLIBC_2.0
GLIBC_2.2
GLIBC_2.1
GLIBCXX_3.4
GLIBC_2.1.3
O segundo usa:
GLIBC_2.0
GLIBC_2.2
GLIBC_2.1
GLIBCXX_3.4.9
GLIBCXX_3.4
GLIBC_2.1.3
Por que o segundo binário usa glibcxx_3.4.9 que está disponível apenas no libstdc ++. So.6.0.9 e não em libstdc ++. So.6.0.8
Qual é o novo recurso gerado por g ++ que exige uma quebra de ABI e force o sistema a ter glibcxx_3.4.9?
Existe uma maneira de desativar esse novo recurso para não exigir glibcxx_3.4.9?
Solução
Para descobrir qual dos símbolos listados glibcxx_3.4.9.9 seu binário realmente depende, faça isso:
readelf -s ./a.out | grep 'GLIBCXX_3\.4\.9' | c++filt
Depois de saber quais símbolos procurar, você pode voltar ao objeto que precisa deles:
nm -A *.o | grep _ZN<whatever>
Finalmente, para amarrar isso de volta à fonte, você pode fazer:
objdump -dS foo.o
e veja qual código está referenciando os símbolos 3.4.9.
Outras dicas
Desde que você pediu, aqui estão os símbolos com pelo menos a versão 3.4.9 da ABI:
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;
Execute o arquivo libstdc++-v3/config/abi/post/i386-linux-gnu/baseline_symbols.txt
Através do Filt C ++, o Grepping para Glibcxx_3.4.9 para entender esses nomes (eles parecem apenas curingas). Eu não fiz isso porque esses nomes se tornam bastante longos e aninhados. As versões posteriores incluem principalmente coisas C ++ 1x. Veja o arquivo libstdc++-v3/config/abi/pre/gnu.ver
para o acima. Ler aqui Sobre o comando Script de Linker de versão.
Bem, a primeira pergunta é como você gerou a lista acima.
Alguém poderia assumir que o compilador é determinístico e, portanto, vincula binários da mesma maneira.
Suponho que fui marcado por não responder diretamente à pergunta, mas um comentário seria bom. Mas ainda acho que você não forneceu as informações corretas e seria bom ver a saída do comando que mostra seu problema.
Supondo que você usou LDD:
Você obteria uma saída que parecia assim:
lib<X>.so.<ver> => /usr/lib/lib<X>.so.<verM> (<Addr>)
Mas este não é o fim da história.
Tentando fazer um LS no arquivo, pode ser um link simbólico
> ls /usr/lilb/lib<X>.so.<verM>
lrwxrwxrwx 1 root root <Date> /usr/lib/lib<X>.so.<verM> -> lib<X>.so.<verM>.<verm>.<verp>