我在玩GDB的rbreak .时候首先注意到了它rbreak . ,然后做了个小例子:
(gdb) file hello_world.out Reading symbols from hello_world.out...done. (gdb) b _init Breakpoint 1 at 0x4003e0 (gdb) b _start Breakpoint 2 at 0x400440 (gdb) run Starting program: /home/ciro/bak/git/cpp/cheat/gdb/hello_world.out Breakpoint 1,_init (argc=1,argv=0x7fffffffd698,envp=0x7fffffffd6a8) at ../csu/init-first.c:52 52 ../csu/init-first.c: No such file or directory. (gdb) continue Continuing. Breakpoint 2,0x0000000000400440 in _start () (gdb) continue Continuing. Breakpoint 1,0x00000000004003e0 in _init () (gdb) info breakpoints Num Type disp Enb Address What 1 breakpoint keep y <MULTIPLE> breakpoint already hit 2 times 1.1 y 0x00000000004003e0 <_init> 1.2 y 0x00007ffff7a36c20 in _init at ../csu/init-first.c:52 2 breakpoint keep y 0x0000000000400440 <_start> breakpoint already hit 1 time
请注意,有2个_init :一个在csu/init-first.c ,另一个似乎来自sysdeps/x86_64/crti.S 我正在谈论的是一个。
是不是_start应该是由链接器设置的入口点,并存储在ELF头? 什么机制使_init先运行? 它的目的是什么?
testing了GCC 4.8,glibc 2.19,GDB 7.7.1和Ubuntu 14.04。
如何在透明窗口中绘制透明的DirectX内容?
C / C ++ / C#:如何做“mount -a”
什么是timeGetTime最好的替代品,以避免环绕?
Minix与Linux学习操作系统devise?
检查CPP程序中的inputredirect
写的主要pty,但不能读奴:(
/ usr / bin / ld:找不到-lGL(Ubuntu 14.04)
有关通话约定的问题
WinAPI SetwindowLongPtr – 更改windowProc
在你的例子中,调试器首先停止的地方不是这个过程的真正开始。
在ELF标题中有程序解释器(动态链接器)的条目。 在Linux 64位上,它的值是/lib64/ld-linux-x86-64.so.2 。 内核将初始指令指针设置为该程序解释器的入口点。 它的符号名也是_start ,就像程序_start 。
动态链接程序完成其工作后,调用程序中的函数,如glibc中的_init ,它调用程序的入口点。
_start中的断点对动态链接器不起作用,因为它只接受程序_start的地址。
您可以使用readelf -h /lib64/ld-linux-x86-64.so.2找到入口点地址。
你也可以在_dl_start设置一个断点,然后打印回溯,看看这个函数是从动态链接器的_start调用的。
如果你下载了glibc的当前源代码,你可以从121行开始在glibc-2.21/sysdeps/x86_64/dl-machine.h找到动态加载器的入口点。