ZEVORN.blog

November 28, 2024

GDB 调试进程手动加载动态库的方法

articlegdb1.0 min to read

如果进程通过 dlopen() 手动加载动态库,某些情况下不能被 GDB 识别调试符号,这个时候可以通过 GDB 的 add-symbol-file file address 命令来手动添加调试符号,address 是动态库在进程中的 text 段 entry 地址,考虑动态库只有加载到进程中,才能得知真正的内存地址,因此我们可以通过 GDB 的 info files 命令,获取这个动态库在进程中的 text 段的 entry 地址。

下面是操作流程:

首先我们把目标动态库先反汇编,作为后续的比对验证对象:

objdump -d demo.so > demo.s

然后使用 gdb 调试目标进程,步骤如下:

(gdb) info files # 获取动态库 text 段 entry 地址...0x00007f1fc9f3ba50 - 0x00007f1fca549490 is .text in /path/demo.so...(gdb) add-symbol-file /path/demo.so 0x00007f1fc9f3ba50 # 加载动态库调试信息(这里编译的动态库自带调试符号)add symbol table from file "demo.so" at                .text_addr = 0x7f1fc9f3ba50(y or n) uReading symbols from demo.sp...done.(gdb) disassemble test_function # 查看任意动态库的函数,进行对比Dump of assembler code for funtion test_function:0x...77adf0<+0>:     sub     $0x218.%rsp0x...77adf7<+7>:     mov    %fs:0x28,%rax...

使用任意编辑器打开刚才反汇编好的 demo.s ,检索这个函数:

000000077adf0 <test_function>:77adf0:   ...  sub     $0x218.%rsp77adf7:   ...  mov    %fs:0x28,%rax

可以看到,GDB 反汇编的地址相对偏移以及指令,和 objdump 反汇编的结果都可以对上,再测试打断点,也可以停在正确位置上面。