问题描述
我有一个与 How to step into openGL APIs by using gdb? 非常相似的问题。我想进入 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 中的错误,是误会吗?如何进入 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,但似乎无论如何都使用了跳跃魔法。奇怪的是,为什么 iris_dri.so
声称 GDB 没有调试信息,因为我现在正在 GDB 中步进它的源代码。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)