Qt Creator/GDB - 调试 session 意外结束

标签 qt gdb qt-creator

1.症状

Qt Creator 中的调试 session 以随机方式意外终止(即,有时它们正常终止),并出现以下错误之一:

  • PC 寄存器不可用(最常见的错误,通常与
    “内部错误:在 psymtab 中读取 pc 0×0,但不在 symtab 中”)
  • SIGSEV
  • SIGILL

  • 这将发生的第一个迹象是当我踩到我的代码行时,我会进入一个汇编程序窗口,进入 NTDLL(通常是 ntdll!LdrFindResource_U+60953)。

    我在 Win7 64 上运行 Qt Creator 2.6.2 和 Qt 5.0.1,使用 QT Creator 的 MinGW(32 位)。此后我在另一台具有 Win732 位的机器上进行了测试,行为是相同的。

    根据我在 Qt 论坛上收到的回复,Rebuild 或 Clean + Build 对这个问题没有任何明显的影响。

    2.第一次解析

    由于第一个错误是最常见的,所以我在网上搜索了它,结果是 this .这似乎是正确的 - 肯定有一个 SIGTRAP,导致了那个错误。

    但是,当我仔细检查所有保存的调试器日志时,我发现有几次没有发生该错误(尽管 SIGTRAP 始终存在)。

    3.图案

    凭借 WinMerge 和一些耐心,我终于能够在所有错误情况下看到一种模式。所有日志(错误和成功)都有这样的内容:
    >=thread-created,id="2",group-id="i1"
    sThread 2 created
    

    除了我的应用程序(在线程 id=“1”上运行)之外,它还创建了第二个线程。但是,所有成功日志都有这样的内容:
    >=thread-exited,id="2",group-id="i1"
    sThread 2 in group i1 exited
    

    因此,我又运行了几个调试 session ,并在遇到第一个断点时检查了正在运行的线程。在所有错误情况下,我得到了这样的信息:
    <455info threads
    >&"info threads\n"
    >~"  Id   Target Id         Frame \n"
    >~"  2    Thread 7160.0x33ec 0x76f1fd71 in ntdll!RtlFindSetBits () from C:\\Windows\\system32\\ntdll.dll\n"
    >~"* 1    Thread 7160.0x128c main (argc=1, argv=0xbb30d8) at ..\\Exeample\\main.cpp:10\n"
    >455^done
    

    使用 Process Explorer,我可以看到第二个线程附加到我的可执行文件(即使我没有创建线程,您也可以看到使用的代码 here)。

    此外,所有错误情况在第二个线程上都有一个 SIGTRAP:
    >~"[Switching to Thread 7160.0x33ec]\n"
    >*stopped,reason="signal-received",signal-name="SIGTRAP",signal-meaning="Trace/breakpoint trap",frame={addr="0x76f1000d",func="ntdll!LdrFindResource_U",args=[],from="C:\\\\Windows\\\\system32\\\\ntdll.dll"},thread-id="2",stopped-threads="all"
    dNOTE: INFERIOR SPONTANEOUS STOP
    

    4. 仔细检查 GDB

    为了确定这是否是 GDB 问题,我运行了几个命令行调试 session ,包括和不包括“-i mi”。从来没有任何对第二个线程的引用,而且我从来没有一个调试 session 意外终止,这就是为什么我认为这个问题的原因可能在 Qt Creator 中。

    5. 求助

    我已经下载了 Qt Creator 的源代码,并在那里寻找了线索,但我并没有走多远。

    gdbengine.cpp 提到了“停止线程”,但我发现唯一提到的是 here .

    有人对我接下来应该检查什么有任何想法/指示吗?

    谢谢你的时间。

    编辑:

    我仍然没有找到造成这种情况的原因,但是在使用 Process Monitor 查看之后,我获得了更多数据。

    创建第二个线程以加载我的应用程序的可执行文件及其所需的 DLL。我已经确认只有当我从 Qt Creator IDE 调试我的应用程序时才会创建第二个线程;如果我从 IDE 运行它(即使用“运行”而不是“调试”),或者如果我从命令行调试它(从命令行启动 gdb),或者如果我从命令行运行它,这永远不会创建第二个线程,并且可执行文件 + DLL 图像由我的应用程序的主(也是唯一的)线程加载。

    在我上面所说的“成功案例”中,即当第二个线程退出时,它会在加载最后一个 DLL 后立即退出,这就是为什么我相信第二个线程仅为此加载而创建。

    最佳答案

    http://www.efnetcpp.org/wiki/Heap_Corruption

    您是两次释放/删除某些内容还是引用已删除的变量?

    上一次我以相当随机的方式在整个 map 上出现错误是因为堆损坏。

    Qt 经常使用一种智能指针来跟踪哪些需要删除,哪些不需要。 (跟踪打开和存储了多少引用以及这些引用何时被删除。)我会查看由多个对象共享的任何变量。

    以下是一些其他用于调试的 Qt 资源:

    http://qt-project.org/doc/qt-4.8/debug.html

    http://qt-project.org/doc/qt-4.8/qobject.html#dumpObjectInfo

    http://qt-project.org/doc/qt-4.8/qobject.html#dumpObjectTree

    正确理解和使用 Qt 对象模型,正确地将对象作为父对象也有助于追踪奇怪的错误。

    http://qt-project.org/doc/qt-4.8/object.html

    缩小错误范围的另一种方法是通过块注释掉代码部分直到错误消失,然后向后工作,重新添加代码。

    最后,另一种查找此类错误的方法是使用您经常使用的版本控制工具(对吗?)。恢复到没有错误的版本,然后与当前版本进行比较,并首先从这些差异开始。

    希望有帮助。

    关于Qt Creator/GDB - 调试 session 意外结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15550265/

    相关文章:

    c - gdb 在 malloc 中卡住

    c++ - qwt 图表示例

    qt - 从另一个 IDE (Qt Creator) 设置 MSVC 编译器的字符集

    c++ - 如何在 Qt Creator 中添加名称以大写字母开头的 c++ 文件?它会自动使它成为小写字母

    c++ - Qt 应用程序中具有共享资源的工作线程

    c++ - Qt:信号调用函数的默认参数

    qt - TreeView - 如何使用角色作为图像源

    qt - OpenCV246 和 Qt LNK1104 无法打开文件 lib.obj

    hadoop - 无法通过 gdb env 中的 libhdfs.so

    gdb - 如何使用 gdb 调试原始二进制文件