GDB && QString

【1】GDB && QString

GDB的print命令仅能打印基本数据类型,而像QString这样的复杂类型就无能为力了!

如果调试时不能看QString的值,很让人抓狂!!!幸好,GDB提供了扩展功能,可以自定义宏命令。

把如下自定义的宏命令放到$HOME/.gdbinit文件中,每次启动GDB时会自动加载。

自定义宏命令内容如下:

 1 define printqstring
 2     printf "(QString)0x%x (length=%i): \"",&$arg0,$arg0.d->size
 3     set $i=0
 4     while $i < $arg0.d->size
 5         set $c=$arg0.d->data[$i++]
 6         if $c < 32 || $c > 127
 7                 printf "\\u0x%04x", $c
 8         else
 9                 printf "%c", (char)$c
10         end
11     end
12     printf "\"\n"
13 end

上面的代码是从坊间摘录的。坊间指导:直接复制到$HOME/.gdbinit文件中就可以。

针对如上指导,问题有二:

1.gdbinit文件找不到怎么办?得先找到gdbinit文件。针对像我这种菜鸟,提示操作如下:

红色框中为gdbinit文件本地实际路径。

2.宏命令添加好后怎么使用呢?

一般使用print命令:print VariableName (简写:p VariableName)

类比使用,针对该宏命令,使用示范:printqstring VariablenName

if 如上操作,的确成功了,请到此为止。否则,请继续往下看。

【2】问题分析

本地使用宏命令过程中发现有问题,提示如下:

"cannot resolve overloaded method `data': no arguments supplied”

异常现象截图如下:

经分析,研究Qt源码QString类过程如下:

 1 class Q_CORE_EXPORT QString
 2 {
 3 public:
 4     typedef QStringData Data;
 5     // ..... TODO
 6     Data *d;
 7     // ..... TODO
 8 };
 9 
10 typedef QTypedArrayData<ushort> QStringData;
11 
12 template <class T>
13 struct QTypedArrayData
14     : QArrayData
15 {
16     // ..... TODO
17     T *data() { return static_cast<T *>(QArrayData::data()); }
18     const T *data() const { return static_cast<const T *>(QArrayData::data()); }
19     // ..... TODO
20 };
21 
22 struct Q_CORE_EXPORT QArrayData
23 {
24     QtPrivate::RefCount ref;
25     int size;
26     uint alloc : 31;
27     uint capacityReserved : 1;
28 
29     qptrdiff offset; // in bytes from beginning of header
30 
31     void *data()
32     {
33         Q_ASSERT(size == 0
34             || offset < 0 || size_t(offset) >= sizeof(QArrayData));
35         return reinterpret_cast<char *>(this) + offset;
36     }
37 
38     const void *data() const
39     {
40         Q_ASSERT(size == 0
41             || offset < 0 || size_t(offset) >= sizeof(QArrayData));
42         return reinterpret_cast<const char *>(this) + offset;
43     }
44     // ..... TODO
45 };

备注:本地调试QT版本为5.3.2

需要修正命令,如下所述。

【3】修正命令

自定义宏命令内容修改如下(ps: 与上个版本差异仅在第5行):

 1 define printqstring
 2         printf "(QString)0x%x (length=%i): \"",&$arg0,$arg0.d->size
 3         set $i=0
 4         while $i < $arg0.d->size
 5             set $c=$arg0.d->data()[$i++]
 6             if $c < 32 || $c > 127
 7                     printf "\\u0x%04x", $c
 8             else
 9                     printf "%c", (char)$c
10             end
11         end
12         printf "\"\n"
13     end

经验证,效果正常。正常使用示例如下所述。

【4】使用示例

4.1 源码如下:

 1 void WinHelpManual::openUrl()
 2 {
 3     QString Html = m_view_list.selectedHtml();
 4     QString strUrlExp = "outline_[0-9]*.htm";
 5     QRegExp urlRegExp(strUrlExp, Qt::CaseSensitive);
 6     if (urlRegExp.indexIn(Html) != -1)
 7     {
 8         QString strWebUrl = urlRegExp.cap(0);  // 匹配到的url
 9         m_view_contents.setUrl(QUrl(m_path + strWebUrl));
10     }
11 }

4.2 正常使用截图如下:

备注:红色框中为字符串值。

【5】利用toStdString()接口

有同事提到可以利用toStdString()接口查看值。

经本地验证,的确可以。但字符串比较长时,打印仍存在问题:

5.1 短字符串,应用示例:

5.2 长字符串,应用示例:

总上所述:建议添加printqstring自定义宏命令,实际应用过程中“因地制宜”。

 

Good Good Study, Day Day Up.

顺序 选择 循环 总结

posted @ 2018-02-07 15:36  kaizenly  阅读(2523)  评论(0编辑  收藏  举报
打赏