システムが使用しているユーザーランドCライブラリを確認するにはどうすればよいですか?この情報を必要とする考えられる理由は次のとおりです。
ldd
。otool --version
同じ情報を提供しているとみなせるかどうかはわかりません。
システムが使用しているユーザーランドCライブラリを確認するにはどうすればよいですか?この情報を必要とする考えられる理由は次のとおりです。
ldd
。otool --version
同じ情報を提供しているとみなせるかどうかはわかりません。
回答:
GNU / Linuxシステムは通常、glibc(Fedora / Redhatファミリー、Arch)またはその親類であるeglibc(Debian / Ubuntuファミリー)を使用します。eglibcは現在glibcにマージされているため(「News」の下に作成されたEGLIBC 2.19 Branchを参照)、近い将来それらはすべてglibcになります。
正確なバージョンを確認する最も簡単な方法はldd
、Cライブラリに付属のask を使用することです。
Fedora 20の場合:
> ldd --version
ldd (GNU libc) 2.18
これはglibc 2.18です。
Raspbian(ARMv6 Broadcom SoC用のDebian 7ポート):
> 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
3行目にあります。
> /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.
/lib/`uname -m`*
パスを使用します。ポータブルな方法は次のようになりますfind /lib/`uname -m`* /usr/lib* -executable -name "*libc.so*" | xargs --version
。良い説明をありがとう。
システムは実際には1つのCライブラリに限定されません。ただし、ほとんどの場合、主に1つだけを使用します。これは、デフォルトのコンパイラでも使用されます。そして、コンパイルするためにソースコードをダウンロードしているので、それがあなたが心配しているものです。
簡単なプログラムから始めます。
#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
、ビルド中にバイナリのDebianパッケージに必要な依存関係の最小バージョンを決定するために、Debianライブラリパッケージに格納されているシンボル情報とともに内部で使用します。基本的に、バイナリDebianパッケージによってエクスポートされたシンボルを調べ、それらのシンボルを含むライブラリの最小バージョンを見つけます。
最も包括的なものではありませんが、明らかな答えは、パッケージマネージャーを確認することです。
rpm -qi glibc
dpkg -l libc6
(残念ながら、glibcにはpkconfig .pc
ファイルがないため、ランナーではありませんpkgconfig --modversion glibc
。)@Gnoucの優れたgetconf
提案も参照してください。
gcc + glibcを使用した最も単純なケースで、私が最初によく使用するのはlibc.so
、ここにある他の回答のいくつかで概説されているように、単に実行することです。引数を渡す必要はありません。デフォルトでバージョンを出力します。これはglibc-2.1まで機能します(glibc-2.0のseg-faultsですが、以前は(現在は廃止されている)glibcbug
スクリプトをチェックしてバージョンを確認できます)。この方法は、musl-libcの最新(> 0.9.15)バージョンでも機能します(3月20日、今日1.0になりました)。uClibcでは機能せず、セグメンテーション違反が発生します。
あなたgcc
が何をしようとしているのかを正確に伝える1つの簡単な方法は、コンパイルです:
#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
ます。これは、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は、今日sulkingされ、。)
まれにdietlibcを使用している場合、実行diet -v
するとバージョンが表示されます。
(FWIWは、ソフトウェア使用したautoconfと、数年にわたって、私はのために、未チェックでより多くの問題がありましたgcc
し、g++
チェックインのためにglibcの機能を備えたよりも要件を。)
GNU libc(ほとんどのLinuxディストリビューションがいずれかの形式で使用するもの)は、厳密な後方互換性を保つために非常に長くなります。したがって、古いバージョン(または「エンタープライズ」ディストリビューション、通常はバージョン、特にCライブラリなどの基本バージョンをフリーズし、厳密なバイナリ互換性を維持しながら修正をバックポートする)で新しいバイナリを実行しようとする場合にのみ、トラブルに遭遇するはずです。他のライブラリで問題が発生する可能性がはるかに高いと思います(C ++には最近のメモリでAPI / ABIの変更がいくつかありましたが、他の一部のライブラリは後方互換性を気にしません)。
残念ながら、確実に見つける唯一の方法は試してみることです。
(これは本質的にゴルディロックスの答えと同じですが、内部で何が起こっているかについてのもう少しの説明があります。)
GNU libcのコア共有ライブラリlibc.so.6
(Linuxの場合、Hurdには異なるSONAMEがあります)には、実行可能ファイルとして呼び出すことができる異常なプロパティ(共有ライブラリ用)があります。実行すると--version
、次のように、GNUユーティリティがで実行されたときに通常印刷されるようなものが出力されます。
$ /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
livesが存在するディレクトリはにない$PATH
ので、どこを探すべきかを知る必要があります。それはであるかもしれない/lib
、/lib64
、/usr/lib
、または(この場合のように)さえwackier何か。便利に、ldd
あなたに教えます:
$ ldd /bin/sh | grep libc
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5660b93000)
もちろん、それが機能するためには、動的にリンクされたバイナリ実行可能ファイルのフルパス名を知っている必要があります。sh
実行可能ファイルがであることが保証されている/bin
(ように多くのため#!
のスクリプトは、それがあることを期待)、そして自身がすることはできません#!
スクリプト。静的にリンクすることもできますが、これを長年行ってきたシステムには遭遇していません。
uClibcやmusl、またはもっとエキゾチックなもので実行している場合、何をするのかわかりません。
$ ldd $(which sh) | grep libc
。:D