1.症状
Qt Creator 中的调试 session 以随机方式意外终止(即,有时它们正常终止),并出现以下错误之一:
“内部错误:在 psymtab 中读取 pc 0×0,但不在 symtab 中”)
这将发生的第一个迹象是当我踩到我的代码行时,我会进入一个汇编程序窗口,进入 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/