如何使用GDB调试解释回溯地址

7

我正在使用backtrace()和backtrace_symbols()函数来输出类似于以下格式的SIGSEGV和其他信号的回溯信息:

0: [0xb750818]
1: /opt/server/libQtScript.so.4(+0x6f42a) [0xb782c42a]
2: /opt/server/libQtScript.so.4(+0x7bffc) [0xb7838ffc]
3: /opt/server/libQtScript.so.4(+0x86946) [0xb7843946]
4: /opt/server/libQtScript.so.4(+0x7c4bc) [0xb78394bc]
5: /opt/server/libQtScript.so.4(+0x86946) [0xb7843946]
6: /opt/server/libQtScript.so.4(+0x9603e) [0xb785303e]
7: /opt/server/libQtScript.so.4(_ZN12QScriptValue4callERKS_RK5QListIS_E+0x2e7) [0xb7891647]

在这种情况下,我对第七个框架很满意,尽管框架1-6给了我一些"+x"地址。
如何在GDB中获取"+0x6f42a"和其他地址的确切行数?而没有描述模块的框架#0是什么意思?
2个回答

10

如何在GDB中获取"+0x6f42a"和其他地址的精确行号?

gdb /opt/server/libQtScript.so.4
(gdb) x/10i 0x6f42a

通常你希望在0x6f42a之前执行指令,因此你可以这样做:

(gdb) x/20i 0x6f42a-30
忽略前几条指令:可能从其中间开始反汇编。通常情况下,反汇编将在几个指令之后重新同步,并在此之后开始显示正确的指令流。
“frame #0”没有描述模块是什么意思?
您的库已被剥离了符号,因此您看到的唯一符号(例如_ZN12QScriptValue4callERKS_RK5QListIS_E)是外部可见的(也称为导出的)符号。
有一个libQtScript.so.4.5.2.debug符号文件在QT_SOURCE/lib目录中。那么我应该复制.debug文件到可执行文件附近以获取带有完整符号的回溯吗?
如果将debug-file-directory设置为$QT_SOURCE/lib,GDB应该会自动加载libQtScript.so.4.5.2.debug中的符号。
更新:
我的意思是不使用GDB获取带符号的回溯信息。
我不相信backtace_symbols()支持加载单独的调试信息文件。

debug-file-directory 是为 GDB 准备的,但我的意思是在不附加 GDB 的情况下获取带有符号的回溯。如何确保 backtrace_symbols() 获取所有符号数据?将 .debug 文件放置是否足够?这些崩溃很少发生,所以我无法在我的开发环境中重现它们。 - Vincas Dargis

0

如果您已经使用调试符号编译了libQTScript,则可以获得更好的回溯,其中包括函数名称和参数值。我不确定如何在没有调试符号的情况下提取相同的信息(尽管如果您有正确的map文件或libQTScript的符号表文件,则应该是可能的)。

但是简单的方法是安装带有调试符号的libqt,并再次运行回溯。如果同时安装了剥离库和调试库,并且gdb选择了剥离的库,请尝试使用LD_LIBRARY_PATH=path/to/debug/libs将gdb指向调试库。(有关在Linux上在gdb中加载核心文件时设置路径的另一种方法,请参见此答案How do I prepend a directory the library path when loading a core file in gdb on Linux


在QT_SOURCE/lib文件夹中有libQtScript.so.4.5.2.debug符号文件。那么,也许我应该将.debug文件复制到可执行文件附近,以获取带有完整符号的回溯? - Vincas Dargis
你可以告诉gdb使用那个文件作为符号表。尝试在gdb内部使用add-symbol-file命令,看看它是否有效。然后再次输入bt来查看回溯信息。 - Albert Veli
add-symbol-file 命令需要一个内存地址作为参数。我认为你可以通过检查命令输出来获取该地址:info sharedlibrary(开始调试,然后发出 info 命令)。 - Albert Veli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接