我有一个在Linux上运行的游戏应用程序。我们是一家游戏公司。我遇到了这种随机崩溃,就像每 24-48 小时发生一次。上次发生这种情况时,我试图查看崩溃线程的回溯,但是 gdb 显示堆栈已损坏,没有符号。现在,当我运行游戏并中断 gdb 时,有时我能够看到此线程的函数调用堆栈,但大多数时候我看不到任何符号。线程是呈现器线程。我们使用的一些游戏库是专有的第三方,没有调试符号。所以我想知道渲染器线程调用堆栈是否在没有符号的情况下深入(库内的各种调用)进入这些库,所以我看不到调用堆栈?如果这是真的,我该如何解决这个问题?如果没有,知道可能是什么原因。
(gdb) bt #0 0x9f488882 in ?? ()
另外,做了一个信息过程映射,对于上面的地址,我发现了以下内容:
0x9f488000 0x9f48a000 0x2000 0x0 /tmp/glyFI8DP (deleted)
这意味着您的第三方库正在使用实时编译来生成一些代码,将其映射到您的进程中,然后将其删除。
在 x86_64 上,GDB 需要展开描述符来展开堆栈,但它无法从已删除的文件中获取它们,因此您不会获得堆栈跟踪。
您有以下几种选择:
-
联系第三方开发人员并询问他们"在这种情况下如何获得堆栈跟踪?
-
使用 GDB
dump
命令转储区域的内容:(gdb) dump /tmp/gly.so 0x9f488000 0x9f48a000
如果幸运的话,生成的二进制文件实际上是一个ELF(不一定是),并且可能包含符号和解展开描述符。使用
readelf --all /tmp/gly.so
查看内部。如果是 ELF 文件,您可以让 GDB 知道这就是在
0x9f488000
映射的内容。您需要在其中找到.text
部分的地址($tstart
下面)(应该在readelf
输出中),然后:(gdb) add-symbol-file /tmp/gly.so 0x9f488000+$tstart