簡體   English   中英

QueueUserAPC - 拋出異常崩潰,可能是 mingw 錯誤

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM