我正在编写一个多线程程序,当抛出一个特定的异常时,它将崩溃。在剥离了越来越多的代码以找到问题后,我现在只剩下一个极其简单的情况,它导致了许多不同的崩溃之一,看起来是随机的。我不知道它为什么这样做。
程序的全部内容如下:
#include <windows.h>
WINAPI DWORD threadFunc(LPVOID x) {
while (true) {
try {
throw 1;
} catch (...) {
}
}
return 0;
}
int main(int argc, char *argv[]) {
CreateThread(NULL, 0, threadFunc, NULL, 0, NULL);
CreateThread(NULL, 0, threadFunc, NULL, 0, NULL);
Sleep(1000);
return 0;
}
据我所知,程序在尝试抛出时崩溃了,但不一定是第一次。
我在调试模式下得到的错误是:
- 段故障,堆栈跟踪包括:
- 00403F70 _Unwind_SjLj_RaiseException(exc=0x474380) (../../../gcc-4.4.1/libgcc/../gcc/unwind.inc:113)
- 00000000 0 x004025f6 __cxa_throw () (??:??)
- 00401380 threadFunc(x=0x0) (D:Software Projectstestcppmain.cpp:6)
- 7C80B729 KERNEL32!GetModuleFileNameA() (C:WINDOWSsystem32 KERNEL32 .dll:??)
- 00000000 0x00000000 in ??() (??:??)
- 程序退出,代码03
和运行时没有调试器:
- "指令0x 某事引用内存在0x 某事",有时一次,有时两次(可能是第二个线程)
- "Process returned -1073741819 (0xC0000005)",访问违规
- "这个应用程序请求运行时以一种不寻常的方式终止它…进程返回3 (0x3)"
我完全被难住了,在这么短的程序中是什么导致了所有这些不同的错误。注释掉其中一个createthread可以阻止任何错误的发生,所以它似乎与多线程和异常抛出的交互有关。
我使用的是32位Windows XP SP3和MinGW 4.4.1
<标题> 更新这个问题似乎是编译器中的一个bug(这是TDM-2 mingw32 4.4.1 -我在问问题时不知道TDM元素,但我不认为它有什么区别)。升级到4.6.1版本后,一切似乎都运行良好。
感谢所有对这个问题做出贡献的人。
标题>更新在注释中澄清了错误立即发生,而不是在进程关闭时,我能看到的唯一剩下的结论是:
- 这是编译器/运行时的一个错误。
- 你正在链接单线程运行时,或者可能需要初始化多线程运行时。你正在调用CreateThread,但是一些c++运行时要求你使用运行时提供的线程创建函数。
你的问题可能是异常处理运行时支持正在卸载,而线程仍然是活动的。当您退出main函数时,运行时将自行关闭。我本来希望运行时比这更健壮,但是你就这样了。
我希望你的问题会消失,如果你确保所有的线程在你退出主函数之前已经终止。在任何情况下,这都是一种良好的做法,您都不希望线程在任何情况下被强制终止。