Quelle version de bibliothèque C mon système utilise-t-il?

Comment puis-je savoir avec certitude quelle bibliothèque C userland mon système utilise? Les raisons possibles d'avoir besoin de cette information include:

Les systèmes GNU / Linux utilisent généralement soit la glibc (famille Fedora / Redhat, Arch) ou son cousin proche, eglibc (famille Debian / Ubuntu); puisque eglibc est maintenant en train d'être fusionné en glibc ( voir EGLIBC 2.19 Branch Created sous "News" ), dans un proche avenir, ils seront de nouveau glibc.

La façon la plus simple de vérifier la version exacte est de requestr à ldd , ldd avec la bibliothèque C.

Sur Fedora 20:

 > ldd --version ldd (GNU libc) 2.18 

C'est la glibc 2.18.

Sur Raspbian (port Debian 7 pour le SoC ARMv6 Broadcom):

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

C'est eglibc 2.13.

Si, pour une raison quelconque, vous avez mélangé et assorti certaines parties ou n'êtes pas sûr de ldd , vous pouvez interroger la bibliothèque C directement.

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

Aucun de ceux-ci n'est exécutable, mais ils fournissent un indice sur l'endroit où en find un.

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

Cependant, ce n'est pas nécessairement si facile, car la bibliothèque C n'a pas à résider quelque part whereis peut le find.

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

Malheureusement, la page de manuel ne fournit pas de numéro de version. ldd toujours utile car tout exécutable lié dynamicment au système (par exemple, presque tout dans /usr/bin ) sera lié à la bibliothèque 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 est sur la troisième ligne.

 > /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. 

Un système n'est pas réellement limité à une bibliothèque C. La plupart, cependant, utilisent principalement un seul, qui sera également celui que le compilateur par défaut utilise. Et puisque vous téléchargez le code source pour comstackr, c'est celui qui vous préoccupe.

Commencez avec un programme sortingvial:

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

comstackz-le en utilisant le compilateur que vous allez utiliser pour le code source, puis utilisez ldd pour savoir où se trouve la bibliothèque 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) 

Vous avez maintenant le path vers la bibliothèque C. Vous pouvez le searchr dans votre gestionnaire de packages pour find le package (par exemple, dpkg -S /lib/x86_64-linux-gnu/libc.so.6 ou rpm -q -f /lib/x86_64-linux-gnu/libc.so.6 ).

Au less dans le cas de eglibc / glibc, vous pouvez l'exécuter:

 $ /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. ⋮ 

Enfin, vous pouvez voir si vous pouvez get des indices de objdump -p /lib/x86_64-linux-gnu/libc.so.6 , en regardant dans la section des définitions de version :

 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 

Notez comment le symbole GLIBC_2.18 a le numéro de version le plus récent parmi les symboles listés, et la version de bibliothèque est en effet 2.18. Il est cependant eglibc (il a l'intention d'être binary compatible avec la glibc 2.18, donc il utilise les mêmes versions de symboles).

Vous pouvez également essayer d'utiliser des ssortingngs pour find quelque chose à ce sujet. Vous voudrez spécifier une longueur minimale plus longue ( -n ) ou utiliser grep pour searchr quelque chose:

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

les deux travaillent pour cet eglibc.

REMARQUE: L'utilitaire de package Debian dpkg-shlibdeps utilise objdump sous le capot, avec les informations de symbole stockées dans les packages de la bibliothèque Debian pour déterminer les versions minimales des dependencies requirejses par les packages Debian binarys au moment de la construction. Fondamentalement, il regarde les symboles exportés par le package Debian binary, puis trouve les versions minimales des bibliothèques qui contiennent ces symboles.

La réponse évidente, bien que pas la plus complète, est de vérifier votre gestionnaire de packages, par exemple

 rpm -qi glibc dpkg -l libc6 

(Malheureusement, la glibc n'a pas de file pkconfig .pc , donc pkgconfig --modversion glibc est un non-runner.) Voir aussi l'excellente suggestion getconf @ Gnouc.

Le cas le plus simple, avec gcc + glibc, et celui que j'utilise le plus souvent en premier est de simplement exécuter libc.so , comme indiqué dans certaines des autres réponses ici. Il n'y a pas besoin de passer d'arguments, il sort sa version par défaut. Cela fonctionne jusqu'à la glibc-2.1 (glibc-2.0 seg-failles, bien que vous puissiez alors vérifier le script glibcbug (maintenant retiré) pour confirmer la version). Cette méthode fonctionne aussi avec les versions récentes (> 0.9.15) de musl-libc (qui vient d'être 1.0 aujourd'hui, le 20 mars). Il ne fonctionne pas avec uClibc, il segfaults.

Une façon simple de dire exactement ce que votre gcc va faire est de comstackr:

 #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; } 

(avec glibc, <stdio.h> inclut <features.h> qui définit les macros GLIBC pertinentes, vous devez <gnu/libc-version.h> pour les déclarations de fonctions).

Ceci attrape des cas plus complexes (libc multiples, et / ou plusieurs compilateurs), en supposant que vous utilisez le bon compilateur (et les drapeaux) bien sûr. (Je soupçonne qu'il ne fera pas la distinction entre eglibc et glibc proprement dit.)

Si vous êtes certain que vous utilisez glibc (ou eglibc), ld confirmera également la version (désolé, ce n'est pas correct).

Si __GNU_LIBRARY__ n'est pas défini, vous obtiendrez des erreurs, alors il est time pour le plan B.

gcc -dumpmachine peut aider, par exemple pour uclibc il a un suffixe -uclibc , comme gcc -dumpspecs | grep dynamic-linker gcc -dumpspecs | grep dynamic-linker . Cela peut également impliquer l'ABI.

gcc -print-file-name=libc.so vous dira quel file le compilateur utilisera pour " -lc ", il s'agit presque certainement d'un script de binding dans votre installation de gcc, que vous pouvez lire en text brut. Cela montrera le path exact vers libc.so Cela fonctionnera également si vous passez des drapeaux comme -m64 ou -m64 .

Dans le cas où vous utilisez uclibc (utilisé par OpenWRT et plus), il définit __UCLIBC_MAJOR__ , __UCLIBC_MINOR__ et __UCLIBC_SUBLEVEL__ ainsi que __UCLIBC__ dans <features.h> , donc il est facilement détecté en utilisant une variation mineure sur l'extrait de code C ci-dessus. Dans l'intérêt de la compatibilité, uClibc peut également définir les macros GNU / GLIBC telles qu'utilisées ci-dessus, il prétend actuellement être glibc-2.2. Il gnu_get_libc_X() pas actuellement les fonctions gnu_get_libc_X() , mais il implémente getconf qui peut aussi induire en erreur (je soupçonne qu'il renvoie une réponse vide pour getconf GNU_LIBC_VERSION , ma build env est boude aujourd'hui donc je ne peux pas confirmer).

Dans le cas improbable où vous utilisez dietlibc , l' option running diet -v affichera la version.

(FWIW, sur plusieurs années avec un logiciel utilisant autoconf J'ai eu plus de problèmes avec les exigences gcc et g++ non vérifiées qu'avec les fonctionnalités de glibc vérifiées).

GNU libc (ce que la plupart des dissortingbutions Linux utilisent sous une forme ou une autre) fait de grands efforts pour garder une rétrocompatibilité ssortingcte. Donc, vous ne devriez rencontrer des problèmes que si vous tentez d'exécuter un nouveau binary sur une ancienne version (ou une dissortingbution "d'entreprise", normalement les versions de base, comme la bibliothèque C, . Je pense que vous êtes beaucoup plus susceptible de rencontrer des problèmes avec d'autres bibliothèques (C ++ a eu quelques changements d'API / ABI dans la memory récente, d'autres bibliothèques ne se soucient pas de la rétrocompatibilité).

Malheureusement, la seule façon de le savoir est d'essayer.

(C'est essentiellement la même chose que la réponse de Goldilocks mais avec plus d'explications sur ce qui se passe sous le capot.)

La librairie partagée principale pour GNU libc, libc.so.6 (sur Linux, Hurd a un SONAME différent), possède la propriété inhabituelle (pour les bibliothèques partagées) que vous pouvez l'appeler en tant qu'exécutable. Si vous le faites, il imprime le genre de choses que les utilitaires GNU impriment généralement lorsqu'ils sont exécutés avec --version , comme ceci:

 $ /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. Comstackd by GNU CC version 4.8.2. Comstackd 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/>. 

Mais bien sûr, le directory où libc.so.6 réside n'est pas dans $PATH , vous devez donc savoir où le searchr. Il pourrait être dans /lib , /lib64 , /usr/lib , ou quelque chose encore plus wackier (comme dans ce cas). Idéalement, ldd vous dira:

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

Pour que cela fonctionne, bien sûr, vous devez connaître le path d'access complet d'un exécutable binary lié dynamicment. L'exécutable sh est garanti dans /bin (parce que tant de scripts #! attendent), et ne peut pas être lui-même un #! scénario. Il pourrait être lié statiquement, mais je n'ai pas rencontré un système qui a fait cela dans de nombreuses années.

Je ne sais pas ce que vous faites si vous courez avec uClibc ou Musl ou quelque chose de plus exotique.

Une autre façon de l'get:

 getconf GNU_LIBC_VERSION