c - Linux C 程序 : How to find the library to which a function belongs

标签 c linux

假设在运行时,我想找出函数“printf”的定义位置。我该怎么做? 我的第一次尝试是打印出“printf”的地址,并将其与进程的虚拟地址映射进行比较:

我的程序:

#include <stdio.h>
#include <unistd.h>

void main()
{
    printf("address of printf is 0x%X\n", printf);
    printf("pid is  %d\n", getpid());
    while (1);
}

输出:

-bash-4.1$ ./a &
[1] 28837
-bash-4.1$ address of printf is 0x4003F8
pid is  28837

但是,这表示该函数是在我自己的程序中定义的!

-bash-4.1$ head /proc/28837/maps 
00400000-00401000 r-xp 00000000 08:06 6946857                            /data2/temp/del/a      <<<<<<< Address 0x4003F8 is in my own program?
00600000-00601000 rw-p 00000000 08:06 6946857                            /data2/temp/del/a
397ec00000-397ec20000 r-xp 00000000 08:11 55837039                       /lib64/ld-2.12.so
397ee1f000-397ee20000 r--p 0001f000 08:11 55837039                       /lib64/ld-2.12.so
397ee20000-397ee21000 rw-p 00020000 08:11 55837039                       /lib64/ld-2.12.so
397ee21000-397ee22000 rw-p 00000000 00:00 0 
397f000000-397f18a000 r-xp 00000000 08:11 55837204                       /lib64/libc-2.12.so
397f18a000-397f38a000 ---p 0018a000 08:11 55837204                       /lib64/libc-2.12.so
397f38a000-397f38e000 r--p 0018a000 08:11 55837204                       /lib64/libc-2.12.so
397f38e000-397f38f000 rw-p 0018e000 08:11 55837204                       /lib64/libc-2.12.so

不应该是对 libc 的调用吗?如何找出这个“printf”或任何其他函数的来源?

最佳答案

您观察到的地址位于过程链接表 (PLT) 中。在编译和链接二进制文件时,当外部(动态链接)符号的位置未知时,使用此机制。

目的是,外部链接只发生在一个地方,PLT,而不是在整个代码中调用符号的所有地方。所以,如果调用printf(),方式是:

main -> printf@PLT -> printf@libc

在运行时,你无法轻易找出你调用的函数位于哪个外部库中;您必须在目的地(PLT)解析操作码,它通常从 .dynamic 部分获取地址并跳转到那里,然后查看符号的实际位置,最后解析/proc/pid/maps 以获取外部库。

关于c - Linux C 程序 : How to find the library to which a function belongs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52599211/

相关文章:

java - 将 JBoss AS 作为 *nix 服务运行时创建文件的权限被拒绝

python - 关闭缓冲

linux - docker linux : How to start multiple console/terminals for one running container?

linux - 删除 sudoers 中没有密码的用户

与 char 和常量的比较总是失败

c - 在 C 中打印字节,仅不可打印字符为十六进制

c++ - 如何在 X86 PC 上为 arm 编译 gcc 编译器

c - 找出当前平台上最大的原生整数类型

c - 为什么 char name[1] 可以容纳 1 个以上的字符?

linux - shell 脚本不工作