Qt Creator / GDB - 调试会话意外结束

时间:2013-03-21 14:28:02

标签: qt gdb qt-creator

1。症状

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

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

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

我正在运行Qt Creator 2.6.2和Qt 5.0.1,使用QT Creator的MinGW(32位),在Win7 64上。我已经在另一台机器上使用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

因此,我运行了更多的调试会话,并在第一个断点被点击时检查了正在运行的线程。在所有错误情况下,我得到了类似的东西:

<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问题,我运行了几个命令行调试会话,包括和不包含“-i mi”。从来没有对第二个线程的引用,我从来没有调试会话意外终止,这就是为什么我认为这个问题的原因可能在Qt Creator中。

5。请求帮助

我已经下载了Qt Creator的来源,我在那里寻找线索,但我没有走得太远。

gdbengine.cpp提到了一个“塞子线”,但我发现的唯一提法是here

任何人对我接下来要检查的内容有什么想法/指针?

感谢您的时间。

编辑:

我仍然没有找到原因,但在使用Process Monitor查看后,我还有更多数据。

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

在上面我称之为“成功案例”的情况下,即当第二个线程退出时,它会在加载最后一个DLL后立即退出,这就是为什么我认为只为此次加载创建了第二个线程。

2 个答案:

答案 0 :(得分:0)

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

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

上次我在地图上以相当随机的方式出现错误是因为堆腐败。

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

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

最后找到这样的bug的另一种方法是使用你经常使用的版本控制工具(对吧?)。恢复到没有bug的版本,然后使用当前版本进行差异,并首先从这些差异开始。

希望有所帮助。

答案 1 :(得分:0)

这与任何类型的内存管理无关,而与调试器如何在Windows上中断进程的方式无关。查看thisthis网址