[英]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.