跟踪同一文件时未找到 execve 文件!

发布于 2024-10-21 03:32:17 字数 1994 浏览 19 评论 0原文

我认识的人在运行“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)
$ find . -name lmutil -exec file {} \;
./bin.linux.x86_64/lmutil: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.4.0, dynamically linked (uses shared libs), for GNU/Linux 2.4.0, stripped
./bin.linux.x86/lmutil: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), for GNU/Linux 2.2.5, stripped
./lmutil: Bourne shell script text executable

someone i know encountered a problem when running 'lmutil' so i asked them to strace -f lmutil. Why is execve failing with "No such file"!!! It makes no sense, since I am straceing the very same file!! What exactly is going on here???

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

Output:

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 output

$ 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)
$ find . -name lmutil -exec file {} \;
./bin.linux.x86_64/lmutil: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.4.0, dynamically linked (uses shared libs), for GNU/Linux 2.4.0, stripped
./bin.linux.x86/lmutil: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), for GNU/Linux 2.2.5, stripped
./lmutil: Bourne shell script text executable

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

爺獨霸怡葒院 2024-10-28 03:32:17

您尝试执行的文件 (.../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 没有帮助的罕见情况之一。

The file you're trying to execute (…/lmutil) exists but its “loader” doesn't exist, where

  • the loader of a native executable is its dynamic loader, for example /lib/ld-linux.so.2;
  • the loader of a script is the program mentioned on its shebang line, e.g., /bin/sh if the script begins with #!/bin/sh.

From the name of the directory, there's a good chance that lmutil is an amd64 Linux binary, looking for /lib64/ld-linux-x86-64.so.2 as its loader, but you have an amd64 Linux kernel running a 386 (i.e. 32-bit) userland. You need to get suitable binaries for your platform.

I consider this situation to be Unix's most misleading error message. Unfortunately fixing it would be hard: the kernel can only report a numeric error code to the caller of the program, so it only has room for “command not found” (ENOENT) and not for the name of the loader it's looking for. This is one of these rare cases where strace doesn't help.

何以畏孤独 2024-10-28 03:32:17

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

Your ldd output refers to /lib64/ld-lsb-x86-64.so.3, but this loader may not actually exist unless (on Ubuntu) you've installed lsb-core package. The postinst script for the package creates the relevant symbolic links in /lib* directories.

小兔几 2024-10-28 03:32:17

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

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

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

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

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

Just a bit of speculation, but my first question would be if the user who is having this problem can run the executable by itself without strace.

Also the execve manual page says that ENOENT will occur if either the file or a required script interepreter or shared library cannot be found. (I notice there is 64-bit-ness involved here. Are all the right libraries available?)

Is the file a native executable or could it be a script of some sort?

This looks like a licensing manager - any chance it has made itself intentionally hard to debug?

Speaking of users, is 'tabitha' in whose directory the executable resides the user having the problem? Or are we looking at a possible complication of trying to run a program installed by another ordinary user rather than in a normal system-wide fashion by root?

┾廆蒐ゝ 2024-10-28 03:32:17

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

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

You can use readelf (any readelf should do, you don't need one from a special crosscompiler toolchain) to check which loader is expected by the dynamically loaded or executable.

$ readelf -l <filename> |grep -i interp
...
[Requesting program interpreter: /system/bin/linker]
一绘本一梦想 2024-10-28 03:32:17

来自 execve 手册页

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

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

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

我写这篇文章是为了警告不要用 strace 和返回值得出结论,即使结果可能是 errnoENOENT无论如何

From the execve manpage:

On success, execve() does not return, on error -1 is returned, and errno is set appropriately.

strace is assuming that -1 means "file not found" as the errno value ENOENT is -1 and strace doesn't make a distinction.

Essentially, then, you can ignore this: the -1 just means that some error occurred. the strace output doesn't tell you what the value of errno is.

I write this as a warning call to not jump to conclusions with strace and return values, even though it may turn out that errno is ENOENT here anyway.

天生の放荡 2024-10-28 03:32:17

您可以看到 execve 返回 ENOENT 。然后在 execve man 中搜索 ENOENT。

文件路径名或脚本或 ELF 解释器不存在。

lmutil 文件存在,并且是 ELF 文件。因此检查ELF解释器是否存在。男子再次说道:

如果可执行文件是动态链接的 ELF 可执行文件,则
PT_INTERP段中命名的解释器用于加载所需的
共享对象。该解释器通常是 /lib/ld-linux.so.2
与 glibc 链接的二进制文件。

我们可以用readelf找到ELF解释器路径,正如@auselen所说:

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

ELF解释器不应该存在于这里。

You can see execve return ENOENT . Then search ENOENT in execve man.

The file pathname or a script or ELF interpreter does not exist.

The lmutil file exist, and is a ELF file. So check whether ELF interpreter exist or not. According the man again:

If the executable is a dynamically linked ELF executable, the
interpreter named in the PT_INTERP segment is used to load the needed
shared objects. This interpreter is typically /lib/ld-linux.so.2 for
binaries linked with glibc .

We can find the ELF interpreter path with readelf as @auselen said:

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

The ELF interpreter should not exist here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文