Cir*_*四事件 7 c linux gcc gdb glibc
我在玩GDB时首先注意到它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
Run Code Online (Sandbox Code Playgroud)
请注意,有两个_init:一个csu/init-first.c,另一个似乎来自sysdeps/x86_64/crti.S.我在谈论那个csu.
不_start应该是链接器设置的入口点,并存储在ELF头中?什么机制_init首先运行?它的目的是什么?
测试了GCC 4.8,glibc 2.19,GDB 7.7.1和Ubuntu 14.04.
调试器在您的示例中首先停止的位置不是该过程的真正开始.
在ELF头中,有一个程序解释器的条目(动态链接器).在Linux 64位上它的值是/lib64/ld-linux-x86-64.so.2.内核将初始指令指针设置为该程序解释器的入口点.它的符号名称也是_start如此,就像程序一样_start.
在动态链接器完成其工作之后,调用程序中的函数,就像_init在glibc中一样,它调用程序的入口点.
断点at _start对动态链接器不起作用,因为它只接受程序的地址_start.
您可以找到入口点地址readelf -h /lib64/ld-linux-x86-64.so.2.
您还可以设置断点_dl_start并打印回溯,以查看是否从动态链接器调用此函数_start.
如果您下载glibc的当前源代码,您可以glibc-2.21/sysdeps/x86_64/dl-machine.h在第121行开始找到动态加载程序的入口点.
| 归档时间: |
|
| 查看次数: |
1728 次 |
| 最近记录: |