在 32 位 Linux 系统上,调用这个
$ /lib/libc.so.6
Run Code Online (Sandbox Code Playgroud)
而在 64 位系统上,这
$ /lib/x86_64-linux-gnu/libc.so.6
Run Code Online (Sandbox Code Playgroud)
在 shell 中,提供如下输出:
GNU C Library stable release version 2.10.1, by Roland McGrath et al.
Copyright (C) 2009 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.4.0 20090506 (Red Hat 4.4.0-4).
Compiled on a Linux >>2.6.18-128.4.1.el5<< system on 2009-08-19.
Available extensions:
The C …Run Code Online (Sandbox Code Playgroud) 如何确定我的系统使用的是哪个用户级 C 库?需要此信息的可能原因包括:
我希望在libc.so.6文件中看到包括printf在内的符号数。我使用nm工具找到它们,但是它说 libc.so.6 中没有符号。
在strace输出中,可执行文件调用的库的路径在调用中open()。这是动态链接的可执行文件使用的系统调用吗?怎么样dlopen()?open()不是我猜想的调用会在程序执行中发挥作用。
我的问题源于我在启动 ffmpeg 时遇到的问题。我已经安装了 ffmpeg,它显示为已安装:
whereis ffmpeg
ffmpeg: /usr/bin/ffmpeg /usr/bin/X11/ffmpeg /usr/share/ffmpeg /usr/share/man/man1/ffmpeg.1.gz
Run Code Online (Sandbox Code Playgroud)
后来,我发现,有些程序依赖于安装本身没有的库,所以我用 ldd 命令检查了缺少什么:
# ldd /usr/bin/ffmpeg
linux-vdso.so.1 => (0x00007fff71fe9000)
libavfilter.so.0 => not found
libpostproc.so.51 => not found
libswscale.so.0 => not found
libavdevice.so.52 => not found
libavformat.so.52 => not found
libavcodec.so.52 => not found
libavutil.so.49 => not found
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f5f20bdf000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f5f209c0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5f205fb000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5f20f09000)
Run Code Online (Sandbox Code Playgroud)
事实证明,我的 ffmpeg 也被 7 个库切断了。我首先认为必须安装这些库中的每一个,但比我想象的要安装一些或全部,但 ffmpeg 不知道它们的位置。我读到 /etc/ld.so.conf 和 /etc/ld.so.cache 包含库的路径,但我很困惑,因为只有一行
/etc/ld.so.conf
cat /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf
Run Code Online (Sandbox Code Playgroud)
但是很长/etc/ld.so.cache …
我有一个名为“alpha”的二进制可执行文件,它需要一个链接库(libz.so.1.2.7),它位于 /home/username/myproduct/lib/libz.so.1.2.7
在通过执行以下命令生成二进制可执行文件之前,我将其导出到我的终端实例。
export LD_LIBRARY_PATH=/home/username/myproduct/lib/:$LD_LIBRARY_PATH
Run Code Online (Sandbox Code Playgroud)
现在,当我生成另一个需要相同库但版本不同的应用程序“bravo”时,即 (libz.so.1.2.8) 在 中可用
/lib/x86_64-linux-gnu/libz.so.1.2.8,系统抛出以下错误。
version `ZLIB_1.2.3.3' not found (required by /usr/lib/x86_64-linux-gnu/libxml2.so.2)
Run Code Online (Sandbox Code Playgroud)
如果我取消设置LD_LIBRARY_PATH,“bravo”启动正常。我了解上述行为是因为LD_LIBRARY_PATH在/etc/ld.so.conf查找链接库时优先于定义的目录路径,因此发生了上述错误。我只是好奇,如果库的第一个实例是不同的版本,为什么 UNIX/LINUX 的开发人员没有设计操作系统根据层次结构搜索其他目录中的链接库。
简单地说,UNIX/LINUX 系统遍历一组目录,直到找到所需的库。但是为什么它在找到预期版本之前不做同样的事情,而不是接受库的第一个实例而不管其版本如何?
与 RedHat/CentOS 相关的问题。我对包和库以及如何将它们固定到固定版本之间有点困惑。
在最近的 libxcb 版本中有一个 X11 翻转错误会影响我的 C 程序。libxcb-1.5-1 没有那个错误。
所以我做了:
# yum remove libxcb-devel
# rpm -Uvh --oldpackage libxcb-1.5-1.el6.i686.rpm
Run Code Online (Sandbox Code Playgroud)
现在错误消失了,我的软件运行良好。
快进几周,错误又回来了。
# yum info libxcb-devel
Loaded plugins: refresh-packagekit, security
Available Packages
Name : libxcb-devel
Arch : i686
Version : 1.9.1
Release : 2.el6
Size : 1.0 M
Repo : sl-security
Run Code Online (Sandbox Code Playgroud)
但是是安装的版本还是通过 repo 可用的版本?我如何知道当前安装的是哪个版本的 libxcb?
$ ll /usr/lib/libxcb.so*
lrwxrwxrwx 1 root root 15 Aug 6 03:38 /usr/lib/libxcb.so.1 -> libxcb.so.1.1.0*
-rwxr-xr-x 1 root root 130752 Oct 14 2014 /usr/lib/libxcb.so.1.1.0*
$ …Run Code Online (Sandbox Code Playgroud) 考虑 的共享对象依赖项/bin/bash,其中包括/lib64/ld-linux-x86-64.so.2(动态链接器/加载器):
ldd /bin/bash
linux-vdso.so.1 (0x00007fffd0887000)
libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f57a04e3000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f57a04de000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f57a031d000)
/lib64/ld-linux-x86-64.so.2 (0x00007f57a0652000)
Run Code Online (Sandbox Code Playgroud)
检查/lib64/ld-linux-x86-64.so.2表明它是一个符号链接/lib/x86_64-linux-gnu/ld-2.28.so:
ls -la /lib64/ld-linux-x86-64.so.2
lrwxrwxrwx 1 root root 32 May 1 19:24 /lib64/ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.28.so
Run Code Online (Sandbox Code Playgroud)
此外,file报告/lib/x86_64-linux-gnu/ld-2.28.so本身是动态链接的:
file -L /lib64/ld-linux-x86-64.so.2
/lib64/ld-linux-x86-64.so.2: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=f25dfd7b95be4ba386fd71080accae8c0732b711, stripped
Run Code Online (Sandbox Code Playgroud)
我想知道:
/lib64/ld-linux-x86-64.so.2) 本身如何动态链接?它在运行时链接自己吗?/lib/x86_64-linux-gnu/ld-2.28.so记录在案以处理 a.out 二进制文件 ( man ld.so),但是/bin/bash …重启电脑后,里面ld.so.cache还有信息,所以我的问题如下:
信息总是保存在那里吗?它不是在重新启动后被删除之类的吗?像 RAM 或浏览器缓存被删除?
在我删除安装了一些共享库的应用程序后,它是否知道也从ld.so.cache? 如果我使用ldconfig它会删除信息吗?它实际上是如何工作的?
如果我正在安装程序,我的计算机如何知道使用已添加的新库?之后apt-get install的ldconfig运行?
我注意到我编译为 gcc 的所有程序都链接到 vdso 库。这是包含对内核的系统调用的库,例如 mmap() 和 fork() 以及其他系统调用吗?
我知道系统调用不是 GNU C 标准库的函数,所以它们的目标代码必须在编译时与应用程序链接的某个库中?
那么 vdso 是那个库吗?
kernel libraries system-calls dynamic-linking shared-library
shared-library ×10
linux ×5
libraries ×4
version ×2
c ×1
etc ×1
executable ×1
ffmpeg ×1
file-command ×1
glibc ×1
kernel ×1
ld ×1
nm ×1
rhel ×1
strace ×1
symbol-table ×1
system-calls ×1
yum ×1