ldd告诉我我的应用程序“不是动态可执行文件”


17

我有一个来自天文学教授的32位应用程序(称为uclsyn)。一年前,我设法使其在CentOS上运行,但是现在,当我设置一个新的CentOS VM时,它将无法运行,并且我也无法找出原因。它总是以“杀死”回来。

这是命令行上的交换:

$ ./uclsyn_linux
Killed

$ ldd ./uclsyn_linux
not a dynamic executable

$ file ./uclsyn_linux
uclsyn_linux: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped

在运行的机器上,“ ldd ./uclsyn_linux”返回完整的依赖项列表。我发现提供了这些共享库的软件包,它们似乎都已安装。

需要包装

  • libSM-1.1.0-7.1.el6.i686
  • libX11-1.3-2.el6.i686
  • libgcc-4.4.6-3.el6.i386
  • glibc-2.12-1.47.el6_2.9.i686
  • libuuid-2.17.2-12.4.el6.i686
  • libXau-1.0.5-1.el6.i686
  • 我检查并已经安装了应用程序本地的大量库。

我的环境

在VirtualBox下运行的CentOS

uname -a:Linux localhost.localdomain 2.6.32-358.el6.i686#1 SMP 2月21日星期四12:50:49 UTC 2013 i686 i686 i386 GNU / Linux


1
大胆猜测:您试图在未安装32位库的64位OS上运行32位二进制文​​件。
2013年

它是一个32位二进制文​​件,但是我安装的OS是CentOS的32位版本。至少那是uname-a命令告诉我的内容吗?
卡尔,

3
@卡尔出于好奇,strace ./uclsyn输出什么?这可能会给我们一个提示,说明首先缺少的是什么。
lgeorget

@lgeorget,它返回:execve(“ ./ uclsyn_linux”,[“ ./uclsyn_linux”],[/ * 56个变量* /] <未完成...> +++被SIGKILL杀死+++
卡尔

@Carl好吧,所以它甚至都没有尝试加载某些库。我从未尝试过strace未正确链接的程序。
lgeorget

Answers:


13

我只是遇到了32位二进制文​​件的问题,解决方案是:

apt-get install gcc-multilib

$ uname -a
Linux bla 2.6.32-028stab094.3 #1 SMP Thu Sep 22 12:47:37 MSD 2011 x86_64 GNU/Linux

3
您是如何发现该lib丢失的?
yehudahs 2015年

1
这个解决方案对我有用。+1
FractalSpace 2015年

@yehudahs我已经在Linux上运行了许多预编译的32位应用程序一段时间了,再加上对它们进行反向工程,因此我收集了一些故障排除经验。:D
lama12345

1
很好,这不仅对我有用,而且我还在挠头,我做错了什么
Marvin Effing

1
对我也
有用

8

这里的错误是由于VirtualMachine上没有足够的RAM。正在运行strace ./programname表示该程序在开始加载任何库之前就已被杀死。增加可用的RAM数量可确保程序可以运行。

有用的回应

其他人也提供了一些有用的响应,例如@slm提供了有用的命令来检查每个库是否存在,而@lgeorget则建议尝试使用该库。 strace命令。


5

您可以发布它链接到的某些库(从原始系统)吗?您可能只需要安装一些缺少的库。

通常在CentOS系统上,只需运行yum命令即可,如下所示:

yum install <package name>

您可以像这样从原始系统向后工作:

$ ldd /bin/ls
    linux-vdso.so.1 =>  (0x00007fff519ff000)
    libselinux.so.1 => /lib64/libselinux.so.1 (0x00000034e8e00000)
    librt.so.1 => /lib64/librt.so.1 (0x00000034e8a00000)
    libcap.so.2 => /lib64/libcap.so.2 (0x0000003d6fe00000)
    libacl.so.1 => /lib64/libacl.so.1 (0x00000034fae00000)
    libc.so.6 => /lib64/libc.so.6 (0x00000034e7200000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00000034e7a00000)
    /lib64/ld-linux-x86-64.so.2 (0x00000034e6e00000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00000034e7e00000)
    libattr.so.1 => /lib64/libattr.so.1 (0x00000034f7600000)

在该输出中,您可以看到我的副本在哪里/bin/ls获取共享的.so库,例如librt.so.1,该库恰好位于此处:/lib64/librt.so.1

知道了这一点,在原始系统上,您可以运行以下命令来找出哪个软件包提供了此库:

$ rpm -qf /lib64/librt.so.1
glibc-2.13-2.x86_64

因此,该包称为glibc-2.13-2.x86_64。因此,要安装它,请执行以下操作:

$ sudo yum install glibc-2.13-2.x86_64

非常感谢帮忙。我走得更远。现在已使用更多信息更新了我的问题,如果您希望使用相同的信息来更新您的回答,将不胜感激。:)
卡尔

yum install <package>是否在问题中引用了那些软件包?
slm

是的,我做到了。除了libuuid.i686(现在已安装)以外,它们都已安装,但是我仍然遇到相同的问题。
卡尔,

2

答案就在您的问题中:您尝试运行一年前为GNU / Linux编译的应用程序,然后尝试使用可能不再兼容或不再可用的新库来运行它。

此时,您有两种选择。如果您可以重新编译它(我怀疑,如果我对您的情况理解得很好),它将运行,因为它将与兼容的库重新链接。否则,您可以尝试构建一种沙箱,例如运行旧版本GNU库的VM,以在其中运行应用程序。


1
这是不正确的。该程序是静态链接的,主机系统上的任何库都不会被引用。尽管ABI仍然可能导致不兼容,但在Linux内核的次要版本之间(假定相同的体系结构)不太可能。
ckhan

1
它不是静态链接的,请参阅的输出file。诸如此类的消息No package xyz found表明所需的库不再可用(至少在相同的程序包中不是这样)。这就是为什么我建议重建程序(如果可能的话)的原因,或者在已知可使用旧库的系统中运行该程序。
lgeorget

不幸的是,这里没有重新编译的选项。我以在这里尝试的相同方式,使它在另一个系统上运行,但是由于某种原因,这次它不喜欢它。
卡尔

错了 地址更改根本不重要。函数的删除或其他ABI中断会在库的主要版本上发生(这很少见),在这种情况下,如果没有安装libfoo2(无论是否已安装libfoo3),则在加载libfoo2时会出错。
psusi

好的,很高兴知道。我以为库中的任何更改都可能破坏链接。我当前正在运行gentoo,并且在升级库时经常不得不重新编译反向依赖项,因此我不认为链接对库的更改是如此抗拒。
lgeorget

0

尝试“ readelf -l uclsyn_linux 请求程序解释器”会告诉您丢失的内容。


1
我遇到readelf -l <file>了具有相同ldd行为(not a dynamic executable)的文件,但没有立即看到任何指示缺少库的信息。我看到Elf file type is EXEC (Executable file)Entry pointProgram HeadersSection to Segment mapping。我到底应该在输出中寻找什么?
StockB

0

Arch Linux中,如果文件是32位elf,则可以安装lib32-gcc-libs(来自multilib存储库)来解决该问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.