检测 ELF 可执行文件中未解析的符号

Detecting unresolved symbols in an ELF executable

假设我有两个文件:

// shared.c (will be compiled to 'shared.so')
#include <stdio.h>
int f() { printf("hello\n"); }

// exe.c (will be compiled to 'exe')
#include <stdio.h>
int f();
int main() { 
    int i;
    scanf("%d", &i);
    if (i == 5) f(); 
}

我编译两个文件如下:

gcc -shared shared.c -o libshared.so
gcc exe.c -o exe -lshared -L.

当我运行 exe 并键入5 时,它会调用f 然后退出。但是,如果我从 shared.c 中删除 f 并重新编译它,仅当我键入 5 时,我才会收到 运行time 符号查找错误。有没有一种方法可以检查 exe 在这种情况下,它的所有符号都可以独立于用户输入工作吗?最好不要 运行 宁它。

您可以使用ldd -r exe 命令来列出共享库依赖项。 这是我在没有 f 函数的示例中的输出:

$ LD_LIBRARY_PATH=. ldd -r ./exe
        linux-vdso.so.1 (0x00007ffcfa7c3000)
        libshared.so => ./libshared.so (0x00007f303a02e000)
        libc.so.6 => /lib64/libc.so.6 (0x0000003e26c00000)
        /lib64/ld-linux-x86-64.so.2 (0x0000003e26400000)
undefined symbol: f     (./exe)

(不要介意LD_LIBRARY_PATH=.部分,用来告诉在当前目录下查找共享库)

@tohava 当您编译可执行文件并使用共享对象 link 时,ld (linker) 检查您的可执行文件所依赖的共享对象列表中是否所有引用的符号都可用,如果存在则抛出错误任何符号都未解析。

所以,当您从共享库中删除 f() 并重建可执行文件时,我不确定您是如何设法得到运行时错误的。 (我自己做了这个练习并得到了 linker 错误)。