[英]QueueUserAPC - throwing exception crashes, possible mingw bug
已解决:我从 mingw 4.6.2 升级到 4.7.0 并且运行良好,我猜这只是一个错误
我开始研究如何正确终止多线程应用程序,我发现了关于如何使用QueueUserAPC
向其他线程发出终止信号的 2 篇文章(第一篇, 第二篇)。
我想我应该试一试,当我从 APCProc 抛出异常时,应用程序一直崩溃。
代码:
#include <stdio.h>
#include <windows.h>
class ExitException
{
public:
char *desc;
DWORD exit_code;
ExitException(char *desc,int exit_code): desc(desc), exit_code(exit_code)
{}
};
//I use this class to check if objects are deconstructed upon termination
class Test
{
public:
char *s;
Test(char *s): s(s)
{
printf("%s ctor\n",s);
}
~Test()
{
printf("%s dctor\n",s);
}
};
DWORD CALLBACK ThreadProc(void *useless)
{
try
{
Test t("thread_test");
SleepEx(INFINITE,true);
return 0;
}
catch (ExitException &e)
{
printf("Thread exits\n%s %lu",e.desc,e.exit_code);
return e.exit_code;
}
}
void CALLBACK exit_apc_proc(ULONG_PTR param)
{
puts("In APCProc");
ExitException e("Application exit signal!",1);
throw e;
return;
}
int main()
{
HANDLE thread=CreateThread(NULL,0,ThreadProc,NULL,0,NULL);
Sleep(1000);
QueueUserAPC(exit_apc_proc,thread,0);
WaitForSingleObject(thread,INFINITE);
puts("main: bye");
return 0;
}
我的问题是为什么会这样?
我使用 mingw 进行编译,我的操作系统是 64 位。
这可能是原因吗?我读到你不应该从 32 位应用程序为在 64 位进程中运行的线程调用QueueApcProc
,反之亦然,但事实并非如此。
编辑:我用 visual studio 的 c++ 编译器 2010 编译了它,它工作得很好,这可能是 gcc/mingw 中的一个错误?
我可以用 VS2005 重现同样的东西。 问题是编译器优化了catch
。 为什么? 因为根据 C++ 标准,如果extern "C"
函数异常退出,会发生什么情况是未定义的。 所以编译器假定SleepEx
(即extern "C"
)永远不会抛出。 在Test::Test
和Test::~Test
内联之后,它发现printf
也没有抛出,因此如果这个块中的某些东西通过异常退出
Test t("thread_test");
SleepEx(INFINITE,true);
return 0;
行为未定义!
在 MSVC 中,代码不适用于发布版本中的/EHsc
开关,但适用于/EHa
或/EHs
EHs ,这告诉它假设 C 函数可能会抛出异常。 也许 GCC 有类似的标志。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.