【问题标题】:How to print <incomplete type> variable in gdb如何在 gdb 中打印 <incomplete type> 变量
【发布时间】:2010-09-18 23:10:02
【问题描述】:

有时 gdb 会为某些类型的变量打印“不完整类型”。这是什么意思?我们如何才能看到这个价值?

【问题讨论】:

  • 即使结构在链接的目标文件中完全定义,我是唯一一个得到这个错误的人吗?有没有办法将 gdb 指向头文件?

标签: gdb


【解决方案1】:

免责声明:我是一名 Python 开发人员,对 C++ 和 Linux 操作系统的运作方式只有一点了解,所以我在下面描述的只是我对我个人遇到的问题的解决方案。

如果您尝试使用来自 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)

  1. 在您的操作系统发行版中查找文件属于哪个包
$ dpkg -S /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
libqt5core5a:amd64: /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
  1. 搜索相关包

    用关键字libqt5core5a搜索返回了2个包,一个是libqt5core5a本身,另一个是libqt5core5a-dbgsym。后者的描述是:“libqt5core5a 的调试符号”

  2. 使用调试符号安装包(我还为一些其他基本 Qt 库安装了调试符号)

$ sudo apt install libqt5core5a-dbgsym libqt5widgets5-dbgsym libqt5gui5-dbgsym
  1. 确保 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.
  1. 现在使用 Qt 类型可以正常工作
(gdb) p e->type()
$4 = QEvent::Paint
(gdb) ptype e
type = class QEvent {
  public:
...
}

【讨论】:

    【解决方案2】:

    我不知道错误的全部含义,但正如 Peter 指出的那样,相关方法的反汇编可以使某些类型定义可用。

    我的例子:

    在一个类的 .h 中,该类包含一个内部辅助类的前向声明,以便外部类可以包含指向它的指针。对应的 .cpp 具有完整的内部辅助类定义。

    在中断外部类的方法时,gdb 报告通过外部类的实例取消引用指向内部类实例的指针的类型不完整。

    对外部类中的一个方法发出反汇编命令允许 gdb 使用之前失败的相同指针来理解内部类的结构。

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题。如果您手动从库中加载符号:

      set auto-solib-add off
      attach thread_id
      shared any_lib
      shared another_lib
      

      您还需要使用相同的命令从声明此对象的库中加载符号。

      【讨论】:

        【解决方案4】:

        这意味着该变量的类型没有被完全指定。例如:

        struct hatstand;
        struct hatstand *foo;
        

        GDB 知道foo 是指向hatstand 结构的指针,但该结构的成员尚未定义。因此,“不完整类型”。

        要打印该值,您可以将其转换为兼容的类型。

        例如,如果您知道 foo 确实是指向 lampshade 结构的指针:

        print (struct lampshade *)foo
        

        或者,您可以将其打印为通用指针,或者将其视为整数:

        print (void *)foo
        print (int)foo
        

        另请参阅 GDB 手册中的这些页面:

        【讨论】:

        • typedef unsigned char byte 的简单 typedef 怎么样?我想在byte* 上查看数据。相反,我得到了data=&lt;incomplete type&gt;。而x/16b data 的结果是 Value can't be converted to integer.
        【解决方案5】:

        我发现,如果您反汇编一个使用不完整结构类型的函数,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' 它将正确显示结构和值。我不知道为什么会这样,但确实如此。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-25
          • 1970-01-01
          • 1970-01-01
          • 2010-09-11
          • 2010-09-20
          相关资源
          最近更新 更多