Что заставляет g ++ включать GLIBCXX_3.4.9? - PullRequest
4 голосов
/ 07 января 2009

Я скомпилировал 2 разных двоичных файла на одном сервере GNU / Linux, используя g ++ версии 4.2.3.

Первый использует:

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

Почему второй двоичный файл использует GLIBCXX_3.4.9, который доступен только в libstdc ++. So.6.0.9 и не в libstdc ++.

Какая новая функция, созданная g ++, требует прерывания ABI и вынуждает систему иметь GLIBCXX_3.4.9?

Есть ли способ отключить эту новую функцию, чтобы не требовать GLIBCXX_3.4.9?

Ответы [ 3 ]

8 голосов
/ 08 января 2009

Чтобы узнать, от какого из перечисленных символов 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.

3 голосов
/ 07 января 2009

Поскольку вы просили об этом, вот символы, имеющие по крайней мере 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 ++ фильтр, добавив GLIBCXX_3.4.9, чтобы разобраться в этих именах (они выглядят только как символы подстановки) Я этого не делал, потому что эти имена становятся довольно длинными и вложенными. Более поздние версии в основном включают c ++ 1x. Смотрите выше файл libstdc++-v3/config/abi/pre/gnu.ver. Прочитайте здесь о команде сценария компоновщика VERSION.

0 голосов
/ 07 января 2009

Ну, первый вопрос: как вы сгенерировали приведенный выше список?
Можно предположить, что компилятор является детерминированным и, таким образом, связывает двоичные файлы одинаково.

Полагаю, я получил оценку за то, что не ответил на вопрос напрямую, но комментарий был бы хорош. Но я все еще думаю, что вы не предоставили правильную информацию, и было бы неплохо увидеть вывод команды, которая показывает вашу проблему.

Предполагается, что вы использовали 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>
...