简体   繁体   English

跟踪同一个文件时找不到 execve 文件!

[英]execve file not found when stracing the very same file!

someone i know encountered a problem when running ' lmutil ' so i asked them to strace -f lmutil .我认识的人在运行“ lmutil ”时遇到了问题,所以我让他们使用strace -f lmutil Why is execve failing with "No such file"!!!为什么execve失败并显示“没有这样的文件”!!! 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 输出

$ 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

The file you're trying to execute ( …/lmutil ) exists but its “loader” doesn't exist, where 您尝试执行的文件( …/lmutil )存在,但其“加载程序”不存在,在哪里

  • the loader of a native executable is its dynamic loader, for example /lib/ld-linux.so.2 ; 本机可执行文件的加载程序是其动态加载程序,例如/lib/ld-linux.so.2
  • the loader of a script is the program mentioned on its shebang line, eg, /bin/sh if the script begins with #!/bin/sh . 脚本加载器是它的家当行中提到的程序,例如, /bin/sh ,如果剧本开头#!/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 (ie 32-bit) userland. 从目录名称来看, lmutil很可能是amd64 Linux二进制文件,正在寻找/lib64/ld-linux-x86-64.so.2作为其加载程序,但是您有一个运行386的amd64 Linux内核(即32位)用户区。 You need to get suitable binaries for your platform. 您需要获取适合您平台的二进制文件。

I consider this situation to be Unix's most misleading error message. 我认为这种情况是Unix最具误导性的错误消息。 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. 不幸的是,修复起来很困难:内核只能将数字错误代码报告给程序的调用者,因此它仅ENOENT “找不到命令”( ENOENT )的空间,而不能容纳正在寻找的加载器的名称。 This is one of these rare cases where strace doesn't help. 这是strace罕见情况之一。

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. 您的ldd输出指向/lib64/ld-lsb-x86-64.so.3,但除非(在Ubuntu上)已安装lsb-core软件包,否则此加载程序可能实际上不存在。 The postinst script for the package creates the relevant symbolic links in /lib* directories. 程序包的postinst脚本在/ lib *目录中创建相关的符号链接。

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. 只是一点推测,但是我的第一个问题将是遇到此问题的用户是否可以在没有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. execve手册页还指出,如果找不到文件或所需的脚本解释器或共享库,则将发生ENOENT。 (I notice there is 64-bit-ness involved here. Are all the right libraries available?) (我注意到这里涉及到64位。是否提供了所有正确的库?)

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? 对用户而言,可执行文件所在的目录中的“ tabitha”是否存在问题? 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? 还是我们正在尝试尝试运行另一个普通用户安装的程序,而不是以root身份在整个系统范围内正常运行,这可能是一种麻烦?

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 (任何readelf都应该做,您不需要特殊的交叉编译器工具链中的任何一个)来检查动态加载的或可执行的文件期望使用哪个加载器。

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

From the execve manpage : execve联机帮助页

On success, execve() does not return, on error -1 is returned, and errno is set appropriately. 成功时,execve()不返回,返回错误-1,并正确设置errno。

strace is assuming that -1 means "file not found" as the errno value ENOENT is -1 and strace doesn't make a distinction. strace假定-1表示“未找到文件”,因为errnoENOENT-1并且strace没有区别。

Essentially, then, you can ignore this: the -1 just means that some error occurred. 从本质上讲,您可以忽略此点: -1表示发生了一些错误。 the strace output doesn't tell you what the value of errno is. strace输出不会告诉您errno的值是什么。

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 . 我写这是一个警告,不要跳到strace和返回值的结论, 即使事实证明errno在这里还是ENOENT

You can see execve return ENOENT .您可以看到 execve 返回 ENOENT 。 Then search ENOENT in execve man .然后在execve man中搜索 ENOENT。

The file pathname or a script or ELF interpreter does not exist.文件路径名或脚本或 ELF 解释器不存在。

The lmutil file exist, and is a ELF file. lmutil 文件存在,并且是一个 ELF 文件。 So check whether ELF interpreter exist or not.所以检查ELF解释器是否存在。 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.如果可执行文件是动态链接的 ELF 可执行文件,则使用 PT_INTERP 段中命名的解释器来加载所需的共享对象。 This interpreter is typically /lib/ld-linux.so.2 for binaries linked with glibc .对于与 glibc 链接的二进制文件,此解释器通常是 /lib/ld-linux.so.2。

We can find the ELF interpreter path with readelf as @auselen said:正如@auselen 所说,我们可以使用 readelf 找到 ELF 解释器路径:

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

The ELF interpreter should not exist here.此处不应存在 ELF 解释器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM