1. 症状
在Qt Creator中进行调试会不可预测地终止(即有时它们正常结束),并出现以下一种错误:
- PC寄存器不可用(最常见的错误,通常显示“内部错误:PC 0×0在读取psymtab时未在symtab中找到”)
- SIGSEV
- SIGILL
这将会发生的第一个迹象是,当我步进我的代码的某一行时,它会带我进入汇编窗口,进入NTDLL(通常是ntdll!LdrFindResource_U + 60953
)。
我正在运行使用QT Creator的MinGW(32位)的Qt Creator 2.6.2和Qt 5.0.1,在Win7 64上。此后,我在另一台安装了Win732位的机器上进行了测试,结果行为相同。
根据我在Qt论坛上收到的回应,重建或清理+构建对此问题没有任何明显影响。
2. 第一次分析
由于第一个错误最常见,所以我在网上搜索了它,这使我找到了这个。它看起来很准确-肯定会出现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
使用“进程资源管理器”,我可以看到这个第二个线程已经附加到我的可执行文件上(即使我没有创建线程,你可以在这里看到被使用的代码)。
此外,所有的错误情况都在第二个线程上出现了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提到了一个“停止线程”,但我唯一发现的提到它的地方是这里。
有人对我下一步应该检查什么有任何想法/指针吗?
感谢你的时间。
编辑:
我仍然没有找到这个问题的原因,但在使用进程监视器查看后,我获得了更多数据。
第二个线程被创建来加载我的应用程序的可执行文件和它需要的DLL。我确认只有当我从Qt Creator IDE调试我的应用程序时,才会创建这个第二个线程。如果我从IDE中运行它(也就是使用“运行”而不是“调试”),或者从命令行调试它(从命令行启动gdb),或者从命令行运行它,就不会创建这个第二个线程,而可执行文件+DLL映像将由我的应用程序的主(唯一)线程加载。
在上面所说的“成功案例”中,也就是当这个第二个线程退出时,它只在加载最后一个DLL后立即退出,这就是我认为这个第二个线程只为此加载而创建的原因。