动态链接失败时提供更好的错误消息

问题描述 投票:0回答:1

如果动态链接失败,我会收到此错误:

/ # /manager
/bin/sh: /manager: not found

对于普通用户来说,这非常令人困惑,因为

/manager
存在。

现在,经过几个小时的搜索,我发现我可以像这样调试它以获得更好的错误消息:

> / # ldd /manager
        /lib64/ld-linux-x86-64.so.2 (0x7f6f93f09000)
Error loading shared library libresolv.so.2: No such file or directory (needed by /manager)
        libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7f6f93f09000)
        libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f6f93f09000)

我想要更好的错误消息。

类似:

/ # /manager
/bin/sh: /manager: Error loading shared library libresolv.so.2: No such file or directory (needed by /manager)

如果这是不可能的,那么通用错误消息会很好:

/ # /manager
/bin/sh: /manager: loading a shared library failed.

这将帮助这个星球上的很多人。

现在我向内核专家提出问题:

是否可以在相关源代码中打补丁,以便将来用户得到更好的错误消息?

这是一个基于alpine的容器镜像。

子问题:相关源码在哪里?

elf alpine-linux dynamic-linking ldd
1个回答
0
投票

错误代码

ENOENT
,对应于消息
not found
,通过
execve(2)
系统调用直接来自内核。从手册页:

艾诺特

文件名或脚本或ELF解释器不存在,或找不到文件所需的共享库或解释器。

它无法在内核级别或 libc 级别“修复”,因为这会破坏众所周知的接口。

如果 shell 是 Bash,则在从文件

execve(2)
中名为
shell_execve()
的函数调用
execute_cmd.c
后,它会向您显示此消息。一些相关代码:

execve (command, args, env);
i = errno; /* this would be ENOENT */

if (executable_file (command) == 0)
    {
      errno = i;
      file_error (command); /* No such file or directory */
    }
else if (i == ENOENT)
  {
    errno = i;
    internal_error (_("%s: cannot execute: required file not found"), command);
  }

修补和包含更好消息的最佳位置就在那里。

Bash 已经尝试改进该消息。如果该文件不存在,则消息将为“没有这样的文件或目录”。当文件存在并且可执行时,消息将更改为“找不到所需的文件”,这更接近您想要的。如果所需的文件是解释器,则消息将更改为“错误的解释器”。

因此,您可以在现有消息中添加“使用 ldd 检查所有动态库是否存在”。要知道哪个库,您需要从

ldd(1)
获取一些代码。

我不知道你的 shell 是什么,但旧版本的 Bash 只会返回“没有这样的文件或目录”,正如你所得到的。

© www.soinside.com 2019 - 2024. All rights reserved.