在XCode 3.xx GDB中打印Qt数据结构(如QList、QString等)

8

我正在尝试在XCode中调试一些Qt容器,但是GDB返回的结果并不有用:

    print l1
$1 = (QSharedPointer<QList<SNAPSHOT> > &) @0x102780650: {
  <QtSharedPointer::ExternalRefCount<QList<SNAPSHOT> >> = {
    <QtSharedPointer::Basic<QList<SNAPSHOT> >> = {
      value = 0x1161e47e0
    }, 
    members of QtSharedPointer::ExternalRefCount<QList<SNAPSHOT> >: 
    d = 0x1161ace00
  }, <No data fields>}
Current language:  auto; currently c++
(gdb) print strQuery
$2 = {
  d = 0x1161e2890

我该如何从l1 (QList)和strQuery (QString)中获得一些有用的输出?我已经尝试使用这个.gdbinit文件,它添加了一些宏,比如“printq4string”,但是使用起来非常痛苦,因为当打印结构体时,我需要手动运行每个成员变量。

你是如何调试这些变量的?这是你代码中某个语句后GDB的终端输出吗?你知道qDebug() << ...方法吗? - leemes
我在GDB中使用print命令,是的,我知道qDebug(),但它只在编译时有效,而且作为唯一的调试工具完全不可扩展。我会比使用std::cerr更倾向于用它,但总体来说它的功能有限。 - user805547
5个回答

4

对于字符串,p my_string.toStdString().c_str() 可行。

(gdb) p my_string.toStdString().c_str()
$5 = 0x55556d10d7d0 "abc 123 test string"

1
好的,即使这个方法在我的当前程序中被内联了,导致它对我无效,但你还是得到了我的点赞。不幸的是,即使使用gcc的__attribute__((always_inline))在-O0构建中也可能发生这种情况。但这绝对是最简单的答案。谢谢。 - Daniel Santos

2

好的,这让我很疯狂,但是我搞定了。

首先确保您的项目设置为使用GCC 4.2进行编译,而不是纯LLVM,如下所示: enter image description here

LLVM现在已经成为XCode 4中的默认编译器,并且它不会为类内部结构添加正确的调试信息。

现在,在您的~/.gdbinit中只需添加:

define pqts
    printf "(QString)0x%x (length=%i): \"",&$arg0,$arg0.d->size
    set $i=0
    while $i < $arg0.d->size
        set $c=$arg0.d->data[$i++]
        if $c < 32 || $c > 127
                printf "\\u0x%04x", $c
        else
                printf "%c", (char)$c
        end
    end
    printf "\"\n"
end

现在,您只需要键入pqts s1,它就会很好地转储您的QString


我已经让QStrings正常工作了,但现在我想让它适用于所有本地类型,包括qMaps、qLists,而且当我打印出一个qlist时,我希望它能够递归并聪明地理解字符串。 - user805547
1
注意:data是一个方法,所以你需要用data()替换data - Hi-Angel

1

我阅读了源代码并想出了这种次优的方法,我将其留给社区来改进:

    QString s1("This should be easy");

    QList<QString> s;
    s.push_back("Can you debug me?");

(gdb) print/c s1.d.data[0]@30
$2 = {84 'T', 104 'h', 105 'i', 115 's', 32 ' ', 115 's', 104 'h', 111 'o', 117 'u', 108 'l', 100 'd', 32 ' ', 98 'b', 101 'e', 32 ' ', 101 'e', 97 'a', 115 's', 121 'y', 0 '\0', 0 '\0', 0 '\0', 0 '\0', 0 '\0', 0 '\0', 0 '\0', 0 '\0', 14 '\016', 0 '\0', 0 '\0'}

(gdb) print/c ((QString*)s.d.array).d.data[0]@20
$12 = {67 'C', 97 'a', 110 'n', 32 ' ', 121 'y', 111 'o', 117 'u', 32 ' ', 100 'd', 101 'e', 98 'b', 117 'u', 103 'g', 32 ' ', 109 'm', 101 'e', 63 '?', 0 '\0', 0 '\0', 0 '\0'}

你怎么才能从 s1.d 中获取数据对象?我只得到“QListData :: Data”中没有名为“data”的成员?这让我崩溃。 - apouche
2
只是一点小提示:在Qt 5.12中,它是print/c *xxx.d[0].data()@20 - scinart

0

通常我使用p *varName.shd,它将其作为一个包含字符串数据的QShared进行转储,但我不确定它是否适用于QList,对于QString肯定适用。


0

我知道这是一个老问题,但我只是将此字符串函数添加到我的实用程序中:

char* q(const QString& string)
{
    return(string.toUtf8().data());
}

然后,p q(myString) 就可以工作了。


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