GNU 工具链调试信息分离和挂载:支持 GDB 调试 RELEASE 版本程序
一般地,release 版本的程序都不带调试信息,无法使用 gdb 调试。
GNU 编译工具链和二进制工具链做法如下:
- gcc/g++ 使用 -g 编译得到目标程序:gcc hello.c -g
- objcopy 复制目标程序中的调试信息:objcopy --only-keep-debug a.out a.debug
- strip/objcopy 去除目标程序中的调试信息: strip --strip-unneeded --strip-debug a.out 或者 objcopy --strip-debug a.out
- gdb 调试目标程序时加载分离的调试信息:gdb -s a.debug -e a.out 或着 objcopy --add-gnu-debuglink=a.debug a.out 再 gdb a.out
通过上面图片可以看到,gdb是从 a.debug 中读取的符号信息。
另外,通过 readlef 读取 a.out 和 a.debug 各个段信息如下:
a.out 的段信息:
There are 31 section headers, starting at offset 0x3908:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000000318 00000318
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.gnu.propert NOTE 0000000000000338 00000338
0000000000000020 0000000000000000 A 0 0 8
[ 3] .note.gnu.build-i NOTE 0000000000000358 00000358
0000000000000024 0000000000000000 A 0 0 4
[ 4] .note.ABI-tag NOTE 000000000000037c 0000037c
0000000000000020 0000000000000000 A 0 0 4
[ 5] .gnu.hash GNU_HASH 00000000000003a0 000003a0
0000000000000024 0000000000000000 A 6 0 8
[ 6] .dynsym DYNSYM 00000000000003c8 000003c8
00000000000000a8 0000000000000018 A 7 1 8
[ 7] .dynstr STRTAB 0000000000000470 00000470
0000000000000084 0000000000000000 A 0 0 1
[ 8] .gnu.version VERSYM 00000000000004f4 000004f4
000000000000000e 0000000000000002 A 6 0 2
[ 9] .gnu.version_r VERNEED 0000000000000508 00000508
0000000000000020 0000000000000000 A 7 1 8
[10] .rela.dyn RELA 0000000000000528 00000528
00000000000000c0 0000000000000018 A 6 0 8
[11] .rela.plt RELA 000000000