旧二进制文件上的ldd怪异

时间:2019-03-07 10:31:53

标签: c linux shared-libraries ldd

我对ldd感到很奇怪

$ sudo ldd ./monit 
    not a dynamic executable

$ readelf -d monit 

Dynamic section at offset 0x25ea90 contains 27 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libpam.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libcrypt.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libresolv.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libnsl.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
...

$ file ./monit 
./monit: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.0, with debug_info, not stripped

$ uname -r -i -m
4.15.0-43-generic x86_64 x86_64


$ file $(which ls)
/bin/ls: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=9567f9a28e66f4d7ec4baf31cfbf68d0410f0ae6, stripped

其他二进制文件和库是针对较新的内核/系统编译的,而ldd成功报告了共享库,我想知道尽管二进制文件是基于同一体系结构构建的,但不同环境之间是否存在任何不兼容性.. 另一个愚蠢的问题是,是否某些共享库会像libpam那样进行升级,如果不插入旧库就可能无法运行二进制文件,那么api是否会发生很大变化?如果新版本是向后兼容的,那么仅建立一个新的动态链接(ln)到旧名称就不够了吗?

-最新- 真是个白痴。我忘记了我拒绝了该主机上分区的执行特权:( ldd命令按预期工作

1 个答案:

答案 0 :(得分:-1)

  

尽管二进制文件是基于同一体系结构构建的,但不同环境之间是否存在任何不兼容性

程序所依赖的“环境”对于许多小东西来说是一个大词。它是一种体系结构(即cpu支持的指令集)或类似的体系结构(主板结构,cpu到mem结构等)或类似的操作系统特定信息(例如具有GNU扩展的POSIX兼容系统或具有dos的DOS系统) .h库)。环境也是库版本,因为它们的api可以更改,并且也像环境变量一样(如果环境中存在此类变量)。

知道“如果不同环境之间存在任何不兼容性”,则您必须手动检查两个版本之间的所有更改。人们将版本控制作为一种可靠且糟糕的通知方式,即发生了某些变化。然后,转到文档中,以人类可读的方式查看发生了什么变化。然后,您必须转到源代码,看看真正发生了什么变化。

  

如果某些共享库如libpam那样升级,则二进制文件有可能不会在不插入旧库的情况下运行,那么api是否会发生很大变化?

首先请注意,大多数unix程序均已获得GNU许可,内容如下:

  

该程序无担保

没有人会保证它在任何情况下都能正常工作。话虽如此,可能如此。可能不会。世界上有太多不同的库,它们是由不同的人编写的,并且它们都经常更改api,因此可能无法正常工作。它可能会起作用。这取决于。

为确保api不会发生太大变化,聪明的人写信给standards。还有standards。还有standards。和标准...

另一方面,是开发人员,他们免费完成所有辛苦工作。他们需要更改api,以便引入新的美观功能或修复错误。因此,他们稍微更改了api。这可能会破坏依赖该api的旧程序。

  

如果新版本向后兼容,那么仅建立一个新的指向旧名称的动态链接(ln)还不够吗?

我这样做的次数超出了我想承认的次数(大多数情况是使用旧的libpng运行eagle),并且大多数情况下它都可以工作。只需尝试一下(通常,在正常的Unix下,以良好的权限在用户下运行),可能会发生的最糟糕的事情是您的程序将发生段错误(嗯,在sudo下可能发生的最糟糕的情况是对您的硬件造成永久性损害并删除所有数据中。)

大多数(不是全部)GNU / Linux系统使用glibc作为C标准库的实现。这应该是最稳定的api,因为所有C程序都依赖它。而且它changes too也不总是向后兼容。