比如在运行时,我想找出函数"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"或任何其他函数的来源?

推荐答案

在运行时,您可以使用gdb来实现这一点:

(terminal 1)$ ./a
pid is  16614
address of printf is 0x400450

(terminal 2)$ gdb -p 16614
(...)
Attaching to process 16614
(...)
0x00000000004005a4 in main ()
(gdb)

(gdb) info sym printf
printf in section .text of /lib/x86_64-linux-gnu/libc.so.6

如果您不想中断程序或不愿意使用gdb,也可以要求ld.so输出一些调试信息:

(terminal 1)$ LD_DEBUG=bindings LD_DEBUG_OUTPUT=syms ./a
pid is  17180
address of printf is 0x400450

(terminal 2)$ fgrep printf syms.17180
    17180:  binding file ./a [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `printf' [GLIBC_2.2.5]

Linux相关问答推荐

Linux/gcc中的文件创建时间系统调用

为什么Read()和cin.get()对输出缓冲区的影响不同?

替换前 3 个字符范围内的所有整数

更改 awk 中的上一个重复行

使用 sed linux 命令和 i sed 命令进行 preprend 时的反向引用

你如何在 CentOS9 上使用 C++ fmt?

有什么方法可以知道在发送之前将在 TCP 上发送多少字节?

如何忽略 diff 命令中的一些差异?

从 Linux 到 Windows 交叉编译 C++ 应用程序的手册?

在 Node.JS 中引用相对于应用程序根目录的文件的正确方法

安装 mod_ssl 亚马逊 Linux

如何排除 tar 的绝对路径?

通过 VM 的 Centos - 镜像列表中没有 URL

在亚马逊 ec2 linux 微型实例上的 virtualenv 中安装 scipy 时遇到问题

'&&' 与 '&' 与 Bash 中的 'test' 命令

Docker Bash 提示不显示 colored颜色 输出

如何链接到 GCC 中特定版本的共享库

命令行 Arduino 编译和上传?

使用 Bash 查找和复制文件

编辑文件时保留 samba 共享的文件权限