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:
JavaScript
x
#include <stdio.h>
#include <unistd.h>
void main()
{
printf("address of printf is 0x%Xn", printf);
printf("pid is %dn", getpid());
while (1);
}
output:
JavaScript
-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!
JavaScript
-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:
JavaScript
(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:
JavaScript
(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]