我有一个与如何使用 gdb 进入 openGL API 非常相似的问题?。我想深入实施
glClear
(例如)。我已经编译了带有调试信息的 Mesa 库,并且我注意到 GDB 中的行为不一致。
(gdb) p glClear
$1 = {<text variable, no debug info>} 0x7ffff74d0ca0 <glClear>
(gdb) b glClear
Breakpoint 3 at 0x7ffff74d0ca0
(gdb) step # IT HAS STEPPED OVER THE BREAKPOINT!?
358 glBindVertexArray(vaoHandle);
我检查
info shared
这个符号的位置,
...
0x00007ffff7482f80 0x00007ffff74e24e2 Yes /home/user/devroot/lib/libGL.so.1
GDB 声称此共享库缺少调试信息(缺少
(*)
),但它确实具有调试信息,可以验证,
> file /home/user/devroot/lib/libGL.so.1
/home/user/devroot/lib/libGL.so.1: symbolic link to libGL.so.1.2.0
> file /home/user/devroot/lib/libGL.so.1.2.0
/home/user/devroot/lib/libGL.so.1.2.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=be24031397474019aa23062146c4d6eef45cb5e0, with debug_info, not stripped
我注意到这是一个“文本符号”
> nm /home/user/devroot/lib/libGL.so.1.2.0 | grep -i 'glclear$'
0000000000068ca0 T glClear
00000000000249ea t __indirect_glClear
这是GDB的一个bug,一个误解吗?如何进入 OpenGL API 函数?
编辑:(额外研究感谢@datenwolf 的提示) 我想到了按照说明一步步进行,这使我在
shared_dispatch_stub_203
中进入了一个名为 libglapi.so.0
的函数。
这做了一些特殊的段寻址,
│ >0x7ffff7412b60 <shared_dispatch_stub_203> mov 0x53461(%rip),%rax # 0x7ffff7465fc8 │
│ 0x7ffff7412b67 <shared_dispatch_stub_203+7> mov %fs:(%rax),%r11 │
│ 0x7ffff7412b6b <shared_dispatch_stub_203+11> jmp *0x658(%r11) │
│ 0x7ffff7412b72 <shared_dispatch_stub_203+18> data16 nopw %cs:0x0(%rax,%rax,1) │
│ 0x7ffff7412b7d <shared_dispatch_stub_203+29> nopl (%rax)
jmp
指令落在_mesa_Clear
中的位置,位于/home/user/devroot/lib/dri/iris_dri.so
库的内存映射中。我现在可以逐步完成这个实现了!
我没有使用glvnd,但似乎无论如何都使用了跳跃魔法。奇怪的是,为什么 GDB 声称
iris_dri.so
没有调试信息,因为我现在正在 GDB 中单步执行它的源代码。
我也遇到这个问题了。现在可以从 gl 函数调试进入 mesa 了吗?