#include <stdio.h> int main(void) { printf("Hello world\n"); return 0; }
当我列出我得到的搬迁时:
test@southpark$readelf -r hello | grep gmon 080495a4 00000106 R_386_GLOB_DAT 00000000 __gmon_start__ 080495b4 00000107 R_386_JUMP_SLOT 00000000 __gmon_start__
当我列出这个文件中的符号我得到:
test@southpark$readelf -s hello | grep gmon 1: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ 48: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
gmon_start有什么需要使用gprof吗?即使我没有编译/链接-pg还是-g,为什么要使用该符号进行重定位?什么图书馆会解决这个符号?
解决方法
The function call_gmon_start initializes the gmon profiling system.
This system is enabled when binaries are compiled with the -pg flag,
and creates output for use with gprof(1). In the case of the scenario
binary call_gmon_start is situated directly proceeding that _start
function. The call_gmon_start function finds the last entry in the
Global Offset Table (also known as __gmon_start__) and,if not NULL,
will pass control to the specified address. The __gmon_start__ element
points to the gmon initialization function,which starts the recording
of profiling information and registers a cleanup function with
atexit(). In our case however gmon is not in use,and as such
__gmon_start__ is NULL.
所以…
是的,它确实与gprof有关
>我不知道为什么这个符号被放在那里.在gprof编译时,可能只是一个占位符?
更新:
好的,所以我编译你的代码有和没有-pg.看起来__gmon_start__映射到编译程序中的一个地址.所以就这样说,我不认为有一个解决这个符号的图书馆,而是程序本身.
与-pg:
akyserr@orion:~$readelf -r hello Relocation section '.rel.dyn' at offset 0x32c contains 1 entries: Offset Info Type Sym.Value Sym. Name 08049fec 00000806 R_386_GLOB_DAT 08048460 __gmon_start__ Relocation section '.rel.plt' at offset 0x334 contains 6 entries: Offset Info Type Sym.Value Sym. Name 0804a000 00000607 R_386_JUMP_SLOT 080483b0 _mcleanup 0804a004 00000107 R_386_JUMP_SLOT 00000000 __monstartup 0804a008 00000207 R_386_JUMP_SLOT 00000000 mcount 0804a00c 00000307 R_386_JUMP_SLOT 00000000 __cxa_atexit 0804a010 00000407 R_386_JUMP_SLOT 00000000 puts 0804a014 00000507 R_386_JUMP_SLOT 00000000 __libc_start_main
objdump __gmon_start__代码:
akyserr@orion:~$objdump -S hello | grep "460 <__gmon_start__>:" -A 20 08048460 <__gmon_start__>: 8048460: 83 ec 1c sub $0x1c,%esp 8048463: a1 20 a0 04 08 mov 0x804a020,%eax 8048468: 85 c0 test %eax,%eax 804846a: 75 2a jne 8048496 <__gmon_start__+0x36> 804846c: c7 05 20 a0 04 08 01 movl $0x1,0x804a020 8048473: 00 00 00 8048476: c7 44 24 04 36 86 04 movl $0x8048636,0x4(%esp) 804847d: 08 804847e: c7 04 24 30 84 04 08 movl $0x8048430,(%esp) 8048485: e8 36 ff ff ff call 80483c0 <__monstartup@plt> 804848a: c7 04 24 b0 83 04 08 movl $0x80483b0,(%esp) 8048491: e8 1a 01 00 00 call 80485b0 <atexit> 8048496: 83 c4 1c add $0x1c,%esp 8048499: c3 ret 804849a: 90 nop 804849b: 90 nop 804849c: 90 nop 804849d: 90 nop
在编译好的hello程序中,__gmon_start__存在,您可以看到__monstartup被调用. (monstartup man page)
没有-pg:
akyserr@orion:~$readelf -r hello Relocation section '.rel.dyn' at offset 0x290 contains 1 entries: Offset Info Type Sym.Value Sym. Name 08049ff0 00000206 R_386_GLOB_DAT 00000000 __gmon_start__ Relocation section '.rel.plt' at offset 0x298 contains 3 entries: Offset Info Type Sym.Value Sym. Name 0804a000 00000107 R_386_JUMP_SLOT 00000000 puts 0804a004 00000207 R_386_JUMP_SLOT 00000000 __gmon_start__ 0804a008 00000307 R_386_JUMP_SLOT 00000000 __libc_start_main
您可以在这里看到__gmon_start__的符号值设置为00000000.