В какой версии библиотеки C используется моя система?

Как я могу точно сказать, в какой библиотеке userland C используется моя система? Возможные причины для этой информации:

6 Solutions collect form web for “В какой версии библиотеки C используется моя система?”

В системах GNU / Linux обычно используется либо glibc (семейство Fedora / Redhat, Arch), либо его близкий родственник, eglibc (семейство Debian / Ubuntu); поскольку eglibc теперь сливается обратно в glibc ( см. раздел EGLIBC 2.19 Branch, созданный в разделе «Новости» ), в ближайшем будущем все они снова станут glibc.

Самый простой способ проверить точную версию – запросить ldd , который поставляется с библиотекой C.

На Fedora 20:

 > ldd --version ldd (GNU libc) 2.18 

Это glibc 2.18.

На Raspbian (порт Debian 7 для ARMv6 Broadcom SoC):

 > ldd --version ldd (Debian EGLIBC 2.13-38+rpi2) 2.13 

Это eglibc 2.13.

Если по какой-либо причине вы смешали и сопоставили некоторые части или иначе не уверены в ldd , вы можете напрямую запросить библиотеку C.

 > whereis libc.so libc: /usr/lib64/libc.a /usr/lib64/libc.so /usr/share/man/man7/libc.7.gz 

Ни один из них не является исполняемым, но они дают представление о том, где его найти.

 > $(find /usr/lib64/ -executable -name "*libc.so*") --version GNU C Library (GNU libc) stable release version 2.18, by Roland McGrath et al. 

Тем не менее, это не обязательно так просто, потому что библиотека C не должна находиться где-то, whereis можно найти.

 > whereis libc.so libc: /usr/share/man/man7/libc.7.gz 

К сожалению, на странице руководства не указан номер версии. ldd прежнему пригодится, поскольку любой рабочий, динамически связанный исполняемый файл в системе (например, почти все в /usr/bin ) будет ссылаться на библиотеку C.

 > ldd /usr/bin/touch /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so (0xb6eed000) librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0xb6ed0000) libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6da1000) /lib/ld-linux-armhf.so.3 (0xb6efb000) libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0xb6d82000) 

libc.so.6 находится на третьей строке.

 > /lib/arm-linux-gnueabihf/libc.so.6 --version GNU C Library (Debian EGLIBC 2.13-38+rpi2) stable release version 2.13, by Roland McGrath et al. 

Система фактически не ограничена одной библиотекой C. Большинство из них, в основном, используют только один, который также будет использоваться компилятором по умолчанию. А поскольку вы загружаете исходный код для компиляции, это тот, который вам нужен.

Начните с тривиальной программы:

 #include <stdio.h> int main() { printf("Hello, world\n"); return 0; } 

скомпилируйте его, используя компилятор, который вы собираетесь использовать для исходного кода, затем используйте ldd чтобы узнать, где находится библиотека C:

 $ ldd ./libc-test linux-vdso.so.1 (0x00007fff2e5fe000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8c8ad98000) /lib64/ld-linux-x86-64.so.2 (0x00007f8c8b171000) 

Теперь у вас есть путь к библиотеке C. Вы можете посмотреть это в менеджере пакетов, чтобы найти пакет (например, dpkg -S /lib/x86_64-linux-gnu/libc.so.6 или rpm -q -f /lib/x86_64-linux-gnu/libc.so.6 ).

По крайней мере, в случае eglibc / glibc вы можете запустить его:

 $ /lib/x86_64-linux-gnu/libc.so.6 GNU C Library (Debian EGLIBC 2.18-4) stable release version 2.18, by Roland McGrath et al. Copyright (C) 2013 Free Software Foundation, Inc. ⋮ 

Наконец, вы можете увидеть, можете ли вы получить ключи от objdump -p /lib/x86_64-linux-gnu/libc.so.6 , просмотрев раздел определения версий :

 Version definitions: 1 0x01 0x0865f4e6 libc.so.6 2 0x00 0x09691a75 GLIBC_2.2.5 3 0x00 0x09691a76 GLIBC_2.2.6 ⋮ 21 0x00 0x06969197 GLIBC_2.17 GLIBC_2.16 22 0x00 0x06969198 GLIBC_2.18 GLIBC_2.17 23 0x00 0x0963cf85 GLIBC_PRIVATE GLIBC_2.18 

Обратите внимание, что символ GLIBC_2.18 имеет самый последний номер версии среди перечисленных символов, а версия библиотеки – это 2.18. Это eglibc, хотя (он предназначен для двоичной совместимости с glibc 2.18, поэтому он использует те же версии символов).

Вы также можете попытаться использовать strings чтобы узнать что-то об этом. Вы хотите указать более длинную минимальную длину ( -n ) или использовать grep для поиска чего-то:

 $ strings /lib/x86_64-linux-gnu/libc.so.6 | grep 'version [0-9]' $ strings /lib/x86_64-linux-gnu/libc.so.6 | grep -iC1 'copyright' 

оба работают для этого eglibc.

ПРИМЕЧАНИЕ. В утилите пакета Debian dpkg-shlibdeps используется objdump под капотом вместе с сохраненной информацией о dpkg-shlibdeps в пакетах библиотеки Debian для определения минимальных версий зависимостей, требуемых бинарными пакетами Debian во время сборки. В основном, он смотрит на символы, экспортируемые бинарным пакетом Debian, а затем находит минимальные версии библиотек, которые содержат эти символы.

Очевидный ответ, хотя и не самый полный, заключается в проверке вашего менеджера пакетов, например

 rpm -qi glibc dpkg -l libc6 

(К сожалению, glibc не имеет pkconfig .pc файла, поэтому pkgconfig --modversion glibc является не-бегуном.) См. Также превосходное предложение getconf .

Простейший случай с gcc + glibc и тот, который я использую в первую очередь, это просто выполнить libc.so , как описано в некоторых других ответах здесь. Нет необходимости передавать какие-либо аргументы, он выводит свою версию по умолчанию. Это работает до glibc-2.1 (gligc-2.0 seg-faults, хотя путь назад вы можете проверить скрипт glibcbug (теперь отставку), чтобы подтвердить версию). Этот метод также работает с последними версиями musl-libc (> 0,9.15) (который только что вышел 1.0 сегодня, 20 марта). Он не работает с uClibc, он segfaults.

Один простой способ рассказать, что именно собирается ваш gcc – это скомпилировать:

 #include <gnu/libc-version.h> #include <stdio.h> int main(int argc, char *argv[]) { printf("%s %s\n",gnu_get_libc_version(),gnu_get_libc_release()); printf("glibc v%i %i.%i\n",__GNU_LIBRARY__,__GLIBC__,__GLIBC_MINOR__); return 0; } 

(с glibc, <stdio.h> включает <features.h> который определяет соответствующие макросы GLIBC, вам нужно <gnu/libc-version.h> для объявлений функций.)

Это захватывает более сложные случаи (несколько libc и / или несколько компиляторов), предполагая, что вы используете правильный компилятор (и флаги), конечно. (Я подозреваю, что он не будет различать eglibc и glibc, хотя.)

Если вы уверены, что используете glibc (или eglibc), то ld также подтвердит версию (извините, это неверно).

Если __GNU_LIBRARY__ не определен, вы получите ошибки, тогда пришло время для плана B.

gcc -dumpmachine может помочь, например, для uclibc он имеет суффикс -uclibc , как может gcc -dumpspecs | grep dynamic-linker gcc -dumpspecs | grep dynamic-linker . Это также может означать ABI.

gcc -print-file-name=libc.so скажет вам, какой файл будет использовать компилятор для « -lc », это почти наверняка скрипт-компоновщик в вашей установке gcc, который вы можете прочитать как обычный текст. Это покажет точный путь к libc.so Это также будет работать, если вы передаете флаги типа -m32 или -m64 .

Если вы используете uclibc (как используется OpenWRT и более), он определяет __UCLIBC_MAJOR__ , __UCLIBC_MINOR__ и __UCLIBC_SUBLEVEL__ а также __UCLIBC__ в <features.h> , поэтому он легко обнаруживается с использованием незначительной вариации в приведенном выше фрагменте кода C. В интересах совместимости uClibc также может определять макросы GNU / GLIBC, как указано выше, в настоящее время он претендует на glibc-2.2. В настоящее время он не реализует функции gnu_get_libc_X() , но реализует getconf который также может ввести в заблуждение (я подозреваю, что он возвращает пустой ответ для getconf GNU_LIBC_VERSION , моя сборка env сейчас сулит, поэтому я не могу подтвердить.)

В маловероятном случае вы используете dietlibc , работает diet -v будет отображать версию.

(FWIW, в течение нескольких лет с программным обеспечением, использующим autoconf. У меня было больше проблем с неконтролируемыми требованиями gcc и g++ чем с проверенными функциями glibc.)

GNU libc (то, что использует большинство дистрибутивов Linux в той или иной форме) подходит для большей совместимости. Таким образом, вы должны столкнуться с трудностями только в том случае, если вы пытаетесь запустить слишком новый двоичный файл на старой версии (или «корпоративном» дистрибутиве, они обычно заморожают версии, особенно базовые, такие как библиотека C, исправления для резервного копирования, сохраняя при этом жесткую двоичную совместимость) , Я считаю, что вы гораздо более склонны сталкиваться с проблемами с другими библиотеками (у C ++ было несколько изменений API / ABI в последней памяти, некоторые другие библиотеки просто не заботятся о обратной совместимости).

К сожалению, единственный способ узнать наверняка – попробовать.

(Это, по сути, то же самое, что и ответ, но с некоторым объяснением того, что происходит под капотом.)

Ядро общей библиотеки для GNU libc, libc.so.6 (на Linux, у Hurd есть другое SONAME), имеет необычное свойство (для разделяемых библиотек), которое вы можете вызывать в качестве исполняемого файла. Если вы это сделаете, он распечатает то, что обычно утилиты GNU печатают при запуске с помощью --version , например:

 $ /lib/x86_64-linux-gnu/libc.so.6 GNU C Library (Debian EGLIBC 2.18-4) stable release version 2.18, by Roland McGrath et al. Copyright (C) 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Compiled by GNU CC version 4.8.2. Compiled on a Linux 3.12.6 system on 2014-03-02. Available extensions: crypt add-on version 2.1 by Michael Glad and others GNU Libidn by Simon Josefsson Native POSIX Threads Library by Ulrich Drepper et al BIND-8.2.3-T5B libc ABIs: UNIQUE IFUNC For bug reporting instructions, please see: <http://www.debian.org/Bugs/>. 

Но, конечно, каталог, в котором живет libc.so.6 не находится в $PATH , поэтому вы должны знать, где его искать. Это может быть в /lib , /lib64 , /usr/lib или что-то даже более странное (как в этом случае). Удобно, ldd скажет вам:

 $ ldd /bin/sh | grep libc libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5660b93000) 

Для этого, конечно, вам нужно знать полный путь к динамически связанному двоичному исполняемому файлу. Предполагается, что исполняемый файл sh находится в /bin (потому что так много сценариев #! Ожидает, что это будет), и он не может быть #! скрипт. Это может быть статически связано, но я не сталкивался с системой, которая делала это в течение многих лет.

Я не знаю, что вы делаете, если вы работаете с uClibc или musl или чем-то более экзотичным.

Другой способ получить это:

 getconf GNU_LIBC_VERSION 
  • Ввод символов ascii в качестве ввода программы
  • StanfordCPPLib Стэнфорда в Linux
  • Как я могу связать свою программу C с библиотекой Arb?
  • Компиляция с недавним gcc на RedHat6: как распространять программное обеспечение?
  • Отладка с помощью программирования оболочки и файлов cpp?
  • Как вызвать фрагментацию памяти на встроенном устройстве на базе Linux?
  • Можно ли записать в другие файловые дескрипторы в C?
  • Conky - форматирование строк
  • Перекрестное компиляция программного модуля
  • 0-127 предел диапазона на WEXITSTATUS в старой Unix?
  • Тестирование кода на C ++ с помощью команд bash
  • Interesting Posts

    Как реплицировать установленный пакет из одного экземпляра Fedora в другой?

    mpirun с ssh и X11

    Модификация и время доступа к файлу?

    Маленький скрипт для обновления цветов GNOME Terminal 3.14.2

    Правильное совпадение слов

    Руководство по сборке ядра Linux: результирующий двоичный файл в 10 раз больше, чем предварительно скомпилированные двоичные файлы

    Как удалить тег APE в файле MP3?

    «Невозможно получить сертификат локального эмитента» и «неизвестное имя tlsv1»,

    Сломанная система из-за обновления libc6

    Как повернуть набор изображений из командной строки?

    Когда все аппаратные ресурсы бесплатны, это может привести к медленному запуску Linux

    Как автоматически открыть окно терминала при нажатии на скрипт?

    Как псевдоним cp с cp -i по умолчанию

    Как распечатать индекс цикла в файл с помощью awk?

    Хранение одного бита информации в пользовательском пространстве

    Linux и Unix - лучшая ОС в мире.