以下是您可以操作的步骤:
cat t.c
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Hello\n");
return 0;
}
gcc -g t.c
gdb -q --args /usr/lib64/ld-linux-x86-64.so.2 ./a.out
(gdb) start
Function "main" not defined.
Starting program: /usr/lib64/ld-linux-x86-64.so.2 ./a.out
Hello
[Inferior 1 (process 7134) exited normally]
到目前为止,一切都与您观察到的相匹配。现在是解决方案:
(gdb) set stop-on-solib-events 1
(gdb) r
Starting program: /usr/lib64/ld-linux-x86-64.so.2 ./a.out
Stopped due to shared library event (no libraries added or removed)
(gdb) c
Continuing.
Stopped due to shared library event:
Inferior loaded /usr/lib64/ld-linux-x86-64.so.2
(gdb) c
Continuing.
Stopped due to shared library event:
Inferior loaded /usr/lib64/libc.so.6
此时,./a.out
也已经被加载,您可以通过以下方式进行确认:
(gdb) info proc map
process 7140
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x400000 0x401000 0x1000 0x0 /tmp/a.out
0x600000 0x601000 0x1000 0x0 /tmp/a.out
0x601000 0x602000 0x1000 0x1000 /tmp/a.out
0x555555554000 0x555555579000 0x25000 0x0 /usr/lib64/ld-2.19.so
0x555555779000 0x55555577a000 0x1000 0x25000 /usr/lib64/ld-2.19.so
0x55555577a000 0x55555577c000 0x2000 0x26000 /usr/lib64/ld-2.19.so
0x7ffff7c2a000 0x7ffff7c2d000 0x3000 0x0
0x7ffff7c2d000 0x7ffff7df0000 0x1c3000 0x0 /usr/lib64/libc-2.19.so
0x7ffff7df0000 0x7ffff7fef000 0x1ff000 0x1c3000 /usr/lib64/libc-2.19.so
0x7ffff7fef000 0x7ffff7ff3000 0x4000 0x1c2000 /usr/lib64/libc-2.19.so
0x7ffff7ff3000 0x7ffff7ff5000 0x2000 0x1c6000 /usr/lib64/libc-2.19.so
0x7ffff7ff5000 0x7ffff7ff9000 0x4000 0x0
0x7ffff7ff9000 0x7ffff7ffa000 0x1000 0x0 /etc/ld.so.cache
0x7ffff7ffa000 0x7ffff7ffd000 0x3000 0x0
0x7ffff7ffd000 0x7ffff7fff000 0x2000 0x0 [vdso]
0x7ffffffde000 0x7ffffffff000 0x21000 0x0 [stack]
0xffffffffff600000 0xffffffffff601000 0x1000 0x0 [vsyscall]
遗憾的是,GDB 不知道它也应该加载 ./a.out
的符号。你需要告诉它:
(gdb) add-symbol-file ./a.out
The address where ./a.out has been loaded is missing
有人会认为GDB所需的地址是来自上面的info proc map
: 0x400000
,但这是错误的。实际上GDB需要的地址是.text
段的起始地址,可以从readelf中获得:
readelf -WS ./a.out | grep text
[13] .text PROGBITS 0000000000400440 000440 000182 00 AX 0 0 16
回到GDB:
(gdb) add-symbol-file ./a.out 0x0000000000400440
add symbol table from file "./a.out" at
.text_addr = 0x400440
Reading symbols from ./a.out...done.
现在我们可以在 main
上打断点:
(gdb) b main
Breakpoint 1 at 0x400531: file t.c, line 6.
(gdb) c
Continuing.
Breakpoint 1, main () at t.c:6
6 printf("Hello\n");
(gdb) n
Hello
7 return 0;
看,完成了!
另外,重新运行二进制文件可能会出现一些故障:
(gdb) r
Starting program: /usr/lib64/ld-linux-x86-64.so.2 ./a.out
Error in re-setting breakpoint 1: Cannot access memory at address 0x40052d
Error in re-setting breakpoint 1: Cannot access memory at address 0x40052d
Stopped due to shared library event (no libraries added or removed)
这是因为
ld-linux
还没有映射
./a.out
,但你可以继续进行。
(gdb) c
Continuing.
Stopped due to shared library event:
Inferior loaded /usr/lib64/ld-linux-x86-64.so.2
(gdb) c
Continuing.
Stopped due to shared library event:
Inferior loaded /usr/lib64/libc.so.6
现在,./a.out
也已经被加载,所以您可以重新启用断点:
(gdb) enable
(gdb) continue
Continuing.
Breakpoint 1, main () at t.c:6
6 printf("Hello\n");