• 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 ""
    "
    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 ""
    "
    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.

    顺序 选择 循环 总结

  • 相关阅读:
    day10_发送邮件终极版
    day10_发送带附件的邮件
    day10_发送普通邮件
    day10_多线程性能测试
    day10_虚拟环境和搭建测试环境的步骤
    codeforces 877B
    codeforces 982C Cut 'em all! (dfs)
    洛谷P1171 售货员的难题 dp
    点集配对问题
    codeforces 891A Pride (数学)
  • 原文地址:https://www.cnblogs.com/Braveliu/p/8426945.html
Copyright © 2020-2023  润新知