Say at runtime, I want to find out where a function “printf” is defined. How would I do this? My first attempt was to print out the address of “printf” and compare it against the virtual address mapping of the process:
my program:
#include <stdio.h> #include <unistd.h> void main() { printf("address of printf is 0x%Xn", printf); printf("pid is %dn", getpid()); while (1); }
output:
-bash-4.1$ ./a & [1] 28837 -bash-4.1$ address of printf is 0x4003F8 pid is 28837
However, this says the function is defined in my own program!
-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
Shouldnt it be a call into libc? How do I find out where this “printf” or any other function came from?
Advertisement
Answer
At runtime, you can use gdb
for this:
(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
If you don’t want to interrupt your program or are reluctant to use gdb
, you may also ask ld.so
to output some debugging info:
(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]