冒落代碼我需要在運行時生成的代碼,執行以下操作:與異常支持
auto v_cleanup = std::shared_ptr<void>(nullptr, [](void *){ cleanup(); });
//...
do_some_danger_thing();
//...
或C當量:
__try {
//...
do_some_danger_thing();
//...
} __finally {
cleanup();
}
的清理()函數保證無例外,但do_some_danger_thing()可能會拋出異常。此運行時代碼不得使用堆棧,這意味着在調用do_some_danger_thing()時,堆棧必須與我們輸入運行時代碼時的狀態相同,除了設置爲運行時代碼的返回地址(原始值保存爲「jmp 「目標,以便返回給調用者)。
由於我們使用的是動態機器代碼,目標平臺固定在x86 CPU上的WIN32上,所以x64 CPU當前未處於焦點狀態。
要做到這一點,我們必須處理任何例外。在WIN32中,C++異常是基於SEH的,所以我們必須對此負責。麻煩的是,我們無法找到一種方法來做到這一點,並使其與其他代碼兼容。我們嘗試了幾個解決方案,但都沒有工作,有時用戶安裝的異常處理程序從未被調用,有時外部異常處理程序被繞過,並且我們收到「未處理的異常」錯誤。
UPDATE:
這似乎是SEH異常處理程序鏈只支持EXE圖像內代碼的情況。如果異常處理程序指向我生成的代碼,它將永遠不會被調用。我必須做的是創建一個靜態異常處理函數存根,然後讓它調用生成的處理函數。
這兩個代碼片段並不相同 - 首先,如果引發異常,您的第一個片段只會調用cleanup();你的第二個片段將永遠稱之爲它。另外,爲什麼沒有堆棧,還是隻能恢復,或...?爲什麼要實現自己的異常處理?我認爲這個問題需要更多關於你想要實現的細節。請解釋你在做什麼,爲什麼等。 –
你是正確的代碼片段...我會解決它。關於「爲什麼實現你自己」的問題,我相信我已經解釋了:我將在運行時生成機器代碼,異常處理只是故事的一部分。是的,您可以在調用do_some_danger_thing之前恢復堆棧,並且如果您決定這樣做,則必須支付更多生成的代碼的成本。 –