如何调试使用调试信息编译的共享库
How to debug shared libraries compiled with debug information
我正在编译一个带有调试符号的程序,该程序链接到共享库 (liballegro),该库也使用调试符号编译。当我尝试进入此共享库的函数时,我看不到任何代码。
file myBin
mybin: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=d4133ef127e81ffb007c4c17e10f4ddaefac6a0f, with debug_info, not stripped
file lib/liballegro-debug.so
liballegro-debug.so.5.2.2: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=dd75ca87e0ed86832ed02a1c40548a055ad4f551, with debug_info, not stripped
GDB 显示如何使用调试信息加载此库:
(gdb) info shared
From To Syms Read Shared Object Library
0x00007ffff7dd9b40 0x00007ffff7df5110 Yes (*) /lib64/ld-linux-x86-64.so.2
0x00007ffff7a5a0d0 0x00007ffff7b84591 Yes correct/path/to/liballegro-debug.so
0x00007ffff76ffd60 0x00007ffff7778eef Yes (*) /usr/lib/libm.so.6
0x00007ffff74e1640 0x00007ffff74eefb1 Yes (*) /usr/lib/libpthread.so.0
[...]
所以我在共享库 (al_load_bitmap) 中的函数调用中放置了一个断点:
90 level->tileset.parent = al_load_bitmap(filename);
al_load_bitmap 的源代码在文件 path/to/src/bitmap_io.c 中,该文件在 gdb 的输出中列出 信息来源
并步入其中:
(gdb) si
0x0000555555555f00 in al_load_bitmap@plt ()
此时我不知道如何查看此函数的源代码,因为 list 命令什么也没有显示。
如何调试此函数内部发生的事情?
PD:我也尝试了 lldb,结果相同,所以我遗漏了一些东西。
谢谢。
al_load_bitmap@plt
是PLT存根(位于主程序中,不是共享对象),没有调试信息。您需要跨过几条指令,然后才能到达实际函数,希望其中包含调试信息。如果惰性绑定处于活动状态(可以使用 LD_BIND_NOW=1
环境变量设置将其禁用),您可能还会遇到动态链接器。
由于这些原因,使用s
(step
)命令进入函数(如果调用的函数有调试信息)会容易很多。
有些情况下 file
报告存在调试信息,但您仍然无法从 GDB 获得有用的行为(例如行号或局部变量访问)。这是因为有几种类型的调试信息,有些 distributions/developers 执行部分剥离或 debuginfo 分离,只留下最低限度以在 ELF 文件中生成回溯(这就是 file
报告为 未剥离).
我正在编译一个带有调试符号的程序,该程序链接到共享库 (liballegro),该库也使用调试符号编译。当我尝试进入此共享库的函数时,我看不到任何代码。
file myBin
mybin: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=d4133ef127e81ffb007c4c17e10f4ddaefac6a0f, with debug_info, not stripped
file lib/liballegro-debug.so
liballegro-debug.so.5.2.2: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=dd75ca87e0ed86832ed02a1c40548a055ad4f551, with debug_info, not stripped
GDB 显示如何使用调试信息加载此库:
(gdb) info shared
From To Syms Read Shared Object Library
0x00007ffff7dd9b40 0x00007ffff7df5110 Yes (*) /lib64/ld-linux-x86-64.so.2
0x00007ffff7a5a0d0 0x00007ffff7b84591 Yes correct/path/to/liballegro-debug.so
0x00007ffff76ffd60 0x00007ffff7778eef Yes (*) /usr/lib/libm.so.6
0x00007ffff74e1640 0x00007ffff74eefb1 Yes (*) /usr/lib/libpthread.so.0
[...]
所以我在共享库 (al_load_bitmap) 中的函数调用中放置了一个断点:
90 level->tileset.parent = al_load_bitmap(filename);
al_load_bitmap 的源代码在文件 path/to/src/bitmap_io.c 中,该文件在 gdb 的输出中列出 信息来源
并步入其中:
(gdb) si
0x0000555555555f00 in al_load_bitmap@plt ()
此时我不知道如何查看此函数的源代码,因为 list 命令什么也没有显示。
如何调试此函数内部发生的事情?
PD:我也尝试了 lldb,结果相同,所以我遗漏了一些东西。
谢谢。
al_load_bitmap@plt
是PLT存根(位于主程序中,不是共享对象),没有调试信息。您需要跨过几条指令,然后才能到达实际函数,希望其中包含调试信息。如果惰性绑定处于活动状态(可以使用 LD_BIND_NOW=1
环境变量设置将其禁用),您可能还会遇到动态链接器。
由于这些原因,使用s
(step
)命令进入函数(如果调用的函数有调试信息)会容易很多。
有些情况下 file
报告存在调试信息,但您仍然无法从 GDB 获得有用的行为(例如行号或局部变量访问)。这是因为有几种类型的调试信息,有些 distributions/developers 执行部分剥离或 debuginfo 分离,只留下最低限度以在 ELF 文件中生成回溯(这就是 file
报告为 未剥离).