有时 gdb 会为某些类型的变量打印“不完整类型”。这是什么意思,我们如何才能看到这个价值?
5 回答
这意味着该变量的类型尚未完全指定。例如:
struct hatstand;
struct hatstand *foo;
GDB 知道这foo
是一个指向hatstand
结构的指针,但该结构的成员尚未定义。因此,“不完整类型”。
要打印该值,您可以将其转换为兼容的类型。
例如,如果您知道这foo
实际上是一个指向lampshade
结构的指针:
print (struct lampshade *)foo
或者,您可以将其打印为通用指针,或者将其视为整数:
print (void *)foo
print (int)foo
另请参阅 GDB 手册中的这些页面:
我发现,如果您反汇编一个使用不完整结构类型 gdb 的函数,则会“发现”结构成员并随后显示它们。例如,假设您有一个字符串结构:
struct my_string {
char * _string,
int _size
} ;
一些通过指针创建和获取字符串的函数:
my_string * create_string(const char *) {...}
const char * get_string(my_string *){...}
和一个创建字符串的测试:
int main(int argc, char *argv[]) {
my_string *str = create_string("Hello World!") ;
printf("String value: %s\n", get_string(str)) ;
...
}
在 gdb 中运行它并尝试“打印 *str”,你会得到一个“不完整类型”的响应。但是,尝试 'disassemble get_string' 然后 'print *str' 它将正确显示结构和值。我不知道为什么会这样,但确实如此。
免责声明:我是一名 Python 开发人员,对 C++ 和 Linux OS 的运行方式只有一点了解,所以我在下面描述的只是我对我个人遇到的问题的解决方案。
如果您尝试使用来自 3rd 方库的类型,请确保这些库没有丢失调试信息。
例子
(gdb) info share Qt
From To Syms Read Shared Object Library
0x00007ffff5336080 0x00007ffff56ba585 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
0x00007ffff4ad3510 0x00007ffff4ef0cbe Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
0x00007ffff47829c0 0x00007ffff47e1ba1 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5DBus.so.5
0x00007ffff40bb5e0 0x00007ffff439dd92 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
0x00007ffff2e581e0 0x00007ffff2e78e4f Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Xml.so.5
0x00007ffff28c8a00 0x00007ffff29d9999 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Network.so.5
0x00007ffff2251750 0x00007ffff2252a46 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5X11Extras.so.5
0x00007ffff1cc9f80 0x00007ffff1cfc861 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5PrintSupport.so.5
0x00007fffee269c10 0x00007fffee297b57 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Svg.so.5
0x00007fffed987560 0x00007fffed98b6a8 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5TextToSpeech.so.5
0x00007fffe980e130 0x00007fffe9900c0c Yes (*) /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5
0x00007fffe69ef650 0x00007fffe69ffe0d Yes (*) /usr/lib/x86_64-linux-gnu/libQt5QuickControls2.so.5
0x00007fffe5c0f890 0x00007fffe5eae1c1 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Quick.so.5
0x00007fffe5522690 0x00007fffe581f636 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Qml.so.5
0x00007fffe51996b0 0x00007fffe5221363 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5QuickTemplates2.so.5
(*): Shared library is missing debugging information.
^ 当前示例中的所有 Qt 库都缺少调试信息。这是因为 qt 库的调试信息来自单独的包,这些包没有被安装。
每当我做whatis
一切都很好:
(gdb) whatis e
type = QEvent *
但是当我试图访问它的成员时
(gdb) p e->type()
Couldn't find method QEvent::type
并试图获得详细的类型描述
(gdb) ptype e
type = class QEvent {
<incomplete type>
} *
解决方案(适用于 Ubuntu 上的 Qt)
- 查找文件属于您的操作系统发行版中的哪个包
$ dpkg -S /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
libqt5core5a:amd64: /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
搜索相关包
使用 keywork 搜索
libqt5core5a
返回 2 个包,一个是libqt5core5a
自身,另一个是libqt5core5a-dbgsym
. 后者的描述说:“libqt5core5a 的调试符号”安装带有调试符号的软件包(我还为其他一些基本的 Qt 库安装了调试符号)
$ sudo apt install libqt5core5a-dbgsym libqt5widgets5-dbgsym libqt5gui5-dbgsym
- 确保
gdb
该库中现在有调试信息
(gdb) info share Qt
From To Syms Read Shared Object Library
0x00007ffff5336080 0x00007ffff56ba585 Yes /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
0x00007ffff4ad3510 0x00007ffff4ef0cbe Yes /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
0x00007ffff47829c0 0x00007ffff47e1ba1 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5DBus.so.5
0x00007ffff40bb5e0 0x00007ffff439dd92 Yes /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
0x00007ffff2e571e0 0x00007ffff2e77e4f Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Xml.so.5
0x00007ffff28c7a00 0x00007ffff29d8999 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Network.so.5
0x00007ffff2250750 0x00007ffff2251a46 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5X11Extras.so.5
0x00007ffff1cc8f80 0x00007ffff1cfb861 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5PrintSupport.so.5
0x00007fffee268c10 0x00007fffee296b57 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Svg.so.5
0x00007fffed985560 0x00007fffed9896a8 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5TextToSpeech.so.5
0x00007fffe95fc130 0x00007fffe96eec0c Yes (*) /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5
0x00007fffe701f650 0x00007fffe702fe0d Yes (*) /usr/lib/x86_64-linux-gnu/libQt5QuickControls2.so.5
0x00007fffe623c890 0x00007fffe64db1c1 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Quick.so.5
0x00007fffe5b4f690 0x00007fffe5e4c636 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5Qml.so.5
0x00007fffe57c66b0 0x00007fffe584e363 Yes (*) /usr/lib/x86_64-linux-gnu/libQt5QuickTemplates2.so.5
(*): Shared library is missing debugging information.
- 现在使用 Qt 类型可以按预期工作
(gdb) p e->type()
$4 = QEvent::Paint
(gdb) ptype e
type = class QEvent {
public:
...
}
我有同样的问题。如果您手动从库中加载符号:
set auto-solib-add off
attach thread_id
shared any_lib
shared another_lib
您还需要使用相同的命令从声明此对象的库中加载符号。
我不知道该错误的全部含义,但正如 Peter 指出的那样,反汇编相关方法可以使这些类型定义中的一些可用。
我的例子:
在一个类的 .h 中,该类包含一个内部辅助类的前向声明,以便外部类可以包含指向它的指针。相应的 .cpp 具有完整的内部助手类定义。
在中断外部类的方法时,gdb 报告了通过外部类的实例取消引用指向内部类实例的指针的不完整类型。
对外部类中的方法之一发出 disasemble 命令允许 gdb 使用先前失败的相同指针来理解内部类的结构。