最近,我努力将现有的 C++ 应用程序移植到新的生产环境(更新的内核、更新的 glibc 等)。即使 ldd 的输出显示我的所有 .so 都被找到,包括 ELF 解释器,执行总是导致“没有这样的文件或目录”。

$ ldd my_app

    libpthread.so.0 => /lib/libpthread.so.0 (0x00007fd41afd6000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007fd41ae52000)
    libm.so.6 => /lib/libm.so.6 (0x00007fd41ad11000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007fd41acf7000)
    libc.so.6 => /lib/libc.so.6 (0x00007fd41ab3a000)
    /lib64/ld-linux-x86-64.so.2 => /lib/ld-linux-x86-64.so.2 (0x00007fd4258b5000) <= ELF Interpreter
    libconfig.so.9 => /usr/lib/libconfig.so.9 (0x00007fd41ab2c000)
    libsensors.so.4 => /usr/lib/libsensors.so.4 (0x00007fd41ab1b000)

$ 文件 my_app
     ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=c8c7eeb2f6bdb96dab7b0cc9ad41aa6e3d610ec7, stripped

$ readelf -a my_app | grep“解释器”
  [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]

由于 ldd 的这个输出,我认为我的问题与解释器没有任何关系。所以我尝试了所有其他可能的解决方法,但没有成功。在网上大量挖掘之后,我遇到了一个相关的问题,该解决方案建议从应用程序的解释器硬编码路径到实际路径创建一个符号链接(symbolic link)。就我而言:
  ln -s /lib/ld-2.29.so /lib64/ld-linux-x86-64.so.2

这终于解决了问题。最后我很沮丧,因为我没有在寻找真正的问题,而且由于 ldd 的误导性输出,我花了很长时间才意识到它。

为什么 ldd 说即使在运行二进制文件时它不会被加载,解释器也在那里?我对 ldd 的使用/输出的解释是错误的吗?

最佳答案



您的新生产环境将 ld-linux-x86-64.so.2 安装到 /lib 而不是 /lib64 。这是非常不寻常和非标准的。许多二进制文件将无法在这样的系统上运行。谁“制造”了这个系统,可能犯了一个严重的错误。


ldd 的工作方式是:它设置一个环境变量 LD_TRACE_OBJECTS=1 并调用它编译时使用的真实解释器。

由于您的系统(错误地)将 ld-linux 安装到 /lib 中,ldd 尽职尽责地调用了 /lib/ld-linux-x86-64.so.2 ,它确实存在,并且实际上告诉了您。

一般来说,ldd 是不可信的,尤其是在一个系统上安装了多个版本的 GLIBC 时。

关于c++ - ldd 显示存在 ELF 解释器,但我仍然得到 "No such file or directory",我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58456757/

10-11 21:53