【问题标题】:execve file not found when stracing the very same file!跟踪同一个文件时找不到 execve 文件!
【发布时间】:2011-07-11 04:24:17
【问题描述】:

我认识的人在运行“lmutil”时遇到了问题,所以我让他们去strace -f lmutil。为什么execve 以“没有这样的文件”失败!!!这是没有意义的,因为我正在跟踪同一个文件!这到底是怎么回事???

strace -f /home/tabitha/Starprogram/FLEXlm_11.7/linux-x86_64-2.3.4/bin/lmutil

输出:

execve("/home/tabitha/Starprogram/FLEXlm_11.7/linux-x86_64-2.3.4/bin/lmutil", ["/home/tabitha/Starprogram/FLEXlm"...], [/* 38 vars */]) = -1 ENOENT (No such file or directory)
dup(2)                                  = 3
fcntl(3, F_GETFL)                       = 0x8002 (flags O_RDWR|O_LARGEFILE)
fstat(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd7cb8b0000
lseek(3, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
write(3, "strace: exec: No such file or di"..., 40strace: exec: No such file or directory
) = 40
close(3)                                = 0
munmap(0x7fd7cb8b0000, 4096)            = 0
exit_group(1)                           = ?

ldd 输出

$ ldd ./lmutil linux-vdso.so.1 => (0x00007fffcd5ff000) libpthread.so.0 => /lib/libpthread.so.0 (0x00007fe40ebbe000) libm.so.6 => /lib/libm.so.6 (0x00007fe40e93b000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007fe40e724000) libc.so.6 => /lib/libc.so.6 (0x00007fe40e3a1000) libdl.so.2 => /lib/libdl.so.2 (0x00007fe40e19d000) /lib64/ld-lsb-x86-64.so.3 => /lib64/ld-linux-x86-64.so.2 (0x00007fe40edf5000) $查找。 -name lmutil -exec 文件 {} \; ./bin.linux.x86_64/lmutil:ELF 64 位 LSB 可执行文件,AMD x86-64,版本 1 (SYSV),适用于 GNU/Linux 2.4.0,动态链接(使用共享库),适用于 GNU/Linux 2.4。 0,剥离 ./bin.linux.x86/lmutil:ELF 32 位 LSB 可执行文件,Intel 80386,版本 1 (SYSV),适用于 GNU/Linux 2.2.5,动态链接(使用共享库),适用于 GNU/Linux 2.2.5,剥离 ./lmutil:Bourne shell 脚本文本可执行文件

【问题讨论】:

  • 可以肯定的是,ldd 的输出是针对…/linux-x86_64-2.3.4/bin/lmutil 的,对吧?这是什么操作系统(对于 Linux:什么发行版),什么版本,什么架构?
  • 好吧..我不确定,现在他们正在尝试使用 CentOS (Qemu).. 操作系统是 Linux,AMD 上的 Ubuntu 最新版本(但我不确定)无论如何,我告诉他们仔细检查架构(32 位与 64 位、intel/amd/sparc、linux/fbsd)以确保不是问题。
  • 为了清楚起见,我只想知道为什么 strace 会给出那个错误(找不到文件).. 并不真正关心修复用户问题(让 lmutil 执行)。 *** 也忽略“find . -name lmutil -exec file {} \; 和相关输出。为此道歉!显然该命令不是由用户运行的。希望我可以编辑它,但我没有;t知道如何*****
  • 如果你没有写lmutil,这不是一个与编程相关的问题,在这种情况下,这里是题外话,我建议请求迁移到Unix Stack Exchange

标签: c linux unix bsd


【解决方案1】:

来自the execve manpage

成功时,execve() 不返回,错误时返回-1,并适当设置errno。

strace 假设 -1 表示“找不到文件”,因为 errno 的值 ENOENT-1strace 没有区别。

那么,基本上,您可以忽略这一点:-1 只是表示发生了一些错误。 strace 输出不会告诉您 errno 的值是什么。

我写这篇文章是为了警告不要用strace 得出结论并返回值,即使结果errno 在这里无论如何都是ENOENT

>

【讨论】:

  • 谢谢!还发现了这篇文章:people.redhat.com/alikins/old_docs/debug.txt
  • 哦,这是一个很好的文档。另外,如果正确,则意味着我的答案是错误的。 :)
  • 不,你读错了strace 输出。 execve返回-1,ENOENT是调用execveerrno的值。
  • @Gilles:就像你没有阅读我之前的评论一样。
  • @Tomalak:如果您意识到自己的答案是错误的,请对其进行编辑以修复它。说“我的答案是错误的”的评论对读者没有帮助:答案应该是独立的,即使他们确实阅读了评论,当我写这篇文章时,除非他们阅读,否则他们不会知道哪里错了我的评论也是。
【解决方案2】:

只是一点猜测,但我的第一个问题是遇到此问题的用户是否可以在不使用 strace 的情况下自行运行可执行文件。

execve 手册页还说,如果找不到文件或所需的脚本解释器或共享库,则会发生 ENOENT。 (我注意到这里涉及 64 位。是否所有正确的库都可用?)

该文件是本机可执行文件还是某种脚本?

这看起来像一个许可管理器 - 有没有可能故意让自己难以调试?

说到用户,'tabitha' 是可执行文件所在的目录中的用户有问题吗?或者我们是否正在考虑尝试运行由另一个普通用户安装的程序而不是通过 root 以正常的系统范围方式安装的程序可能会出现复杂情况?

【讨论】:

  • 如果它不能被操作系统运行,strace 也不能用它做任何事情,这就是你在这里看到的。您可能需要检查该用户的读取和执行权限,然后可能需要检查库问题。
【解决方案3】:

您尝试执行的文件 (…/lmutil) 存在,但其“加载程序”不存在,其中

  • 本机可执行文件的加载器是其动态加载器,例如/lib/ld-linux.so.2
  • 脚本的加载程序是在其 shebang 行中提到的程序,例如,如果脚本以 #!/bin/sh 开头,则为 /bin/sh

从目录名称来看,lmutil 很有可能是一个 amd64 Linux 二进制文件,正在寻找 /lib64/ld-linux-x86-64.so.2 作为它的加载器,但是你有一个运行 386(即 32 位)用户空间的 amd64 Linux 内核.您需要为您的平台获取合适的二进制文件。

我认为这种情况是 Unix 最具误导性的错误信息。不幸的是,修复它会很困难:内核只能向程序的调用者报告一个数字错误代码,所以它只有“找不到命令”(ENOENT)的空间,而不是它正在寻找的加载程序的名称.这是strace 不起作用的罕见情况之一。

【讨论】:

  • 好库存在 - ldd /whatever/lmutil 没问题。它也是一个二进制文件 - 文件 /whatever/lmutil。该软件包是由用户在他的笔记本电脑上安装的,因此它不是 remoteFS。
  • 忽略查找。 -name lmutil -exec 文件 {} \; (该输出不是由用户生成的)这是一个错误,需要编辑掉。
  • @paleywiener:那么ldd ./lmutil 呢,它是否运行在您尝试 strace 的同一个可执行文件上?缺少加载程序是我能想到的执行现有文件失败并出现ENOENT 的唯一解释,因此我也倾向于对报告的这一部分提出质疑。
  • @Gilles:你拯救了我的一天!这正是我的问题(我试图在 64 位 Ubuntu 12.04 安装上运行 32 位可执行文件而没有意识到),并且只是发出 sudo apt-get install ia32-libs 使问题消失了。
  • @reinierpost 在 Ubuntu 12.04 上,您可以使用 multiarch,它可以让您使用比老式 ia32-libs 方式更多的库。见help.ubuntu.com/community/MultiArch
【解决方案4】:

您的 ldd 输出指的是 /lib64/ld-lsb-x86-64.so.3,但除非(在 Ubuntu 上)您已安装 lsb-core 软件包,否则此加载程序可能实际上并不存在。包的 postinst 脚本在 /lib* 目录中创建相关的符号链接。

【讨论】:

  • 这为我解决了这个问题:“ldd”输出显示“/lib64/ld-lsb-x86-64.so.3 => /lib64/ld-linux-x86-64.so。 2”,但我的系统(Ubuntu 16.04)上没有“/lib64/ld-lsb-x86-64.so.3”。安装“lsb-core”包创建了这个符号链接,然后 lmutil 工作。
【解决方案5】:

您可以使用readelf(任何 readelf 都应该这样做,您不需要来自特殊交叉编译器工具链的工具链)来检查动态加载或可执行文件需要哪个加载器。

$ readelf -l <filename> |grep -i interp
...
[Requesting program interpreter: /system/bin/linker]

【讨论】:

  • +1 实际上提供了一种可行的方法来为 ELF 可执行文件调试此问题。虽然从技术上回答一个单独的问题,但这是一个非常相关且自然的后续问题。
猜你喜欢
  • 2017-03-15
  • 2018-07-18
  • 2012-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多