簡體   English   中英

是否有任何方法導致整個堆棧幀在C ++中展開? (除了使用例外)

[英]Is there any method that causes whole stack frame unwinding in C++? (except using exception)

我一直在寫一個延續 - 特定的,協程 - 庫。 它類似於std :: thread(除了它是合作的) - 每個執行上下文都在continuation對象中表示。

問題是關於持續對象的破壞。 如果在執行上下文沒有正常退出時調用continuation對象的dtor,則應該強制它被銷毀該對象的上下文關閉。

這樣,堆棧幀中的每個C ++對象都不會被正確銷毀。 對於任何人來說這可能不是一個令人愉快的情況 - 所以我決定找到一個解決方案。

在第一次,我想使用異常來展開堆棧幀,如下所示。 (請注意,下面只是有缺陷的偽代碼。)

coroutine::~coroutine()
{
    status = FORCED_EXIT;
    switch_to(*this);
}

void coroutine::yield(coroutine& other_coroutine)
{
     // switch to other context, halt until invocation by other context
    switch_to(other_coroutine);

    if (status_ != FORCED_EXIT) {
        return; // resume
    } else {
        throw ContextClosingException;
    }
}

void coroutine::entrypoint()
{
    try {
        entry_function_();
    } catch(ContextClosingException& e) {
        switch_to(caller_coroutine);
    }
}

但是,我發現了一些嚴重的缺陷。 如下所述“吞下異常”的任何用戶代碼將完全打破協作調度的假設。

try {
    ...
} catch(...) { // ContextClosingException 
    // do nothing, just swallow exception.
}

所以我需要找到其他方法來調用堆棧展開(或者在繼續中破壞堆棧對象的任何其他方法)。 標准一致性方式會很好 - 但是延續實現本身依賴於特定於平台的API,因此非可移植方式是可以接受的。 (我正在使用win32)

C ++標准中沒有任何內容允許展開除異常之外的堆棧。 可以在C ++ 11之后提出協程(或對corountines的支持)(在Going Native會議期間談到)。

您將不得不使用特定於操作系統的C調用(如果存在,我不這么認為),但很可能您自己使用ASM。 您可以查看boost.context庫以獲取示例解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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