2010-06-17 66 views
2

環境是各種運平臺VC++ 9(XP及更高版本)是否安全趕上EXCEPTION_GUARD_PAGE

我正在寫一個未處理的異常處理。我的內核日子裏有一個模糊的回憶,那就是抓住EXCEPTION_GUARD_PAGE是不好的,因爲這是生成的,它告訴操作系統放大堆棧。

我的問題是雙重的:

  1. 這樣的異常可發生在用戶空間?

  2. 如果是這樣,是否可以接受它?

我對使用它做任何事情都不感興趣。我只是想知道是否需要將特殊代碼放入而不是趕上它(因爲我現在捕捉所有內容)。

__Update:__

我回憶起我的來源,這是Raymond Chen的博客(http://blogs.msdn.com/b/oldnewthing/archive/2006/09/27/773741.aspx

我最初擔心的是捕獲所有異常的時候,如果我抓住一個EXCEPTION_GUARD_PAGE,我可能防止操作系統看到異常並擴大堆棧。

在進一步的思考中,我懷疑EXCEPTION_GUARD_PAGE可能在生成它的讀/寫操作期間在內核中處理,因此永遠無法達到我的用戶空間代碼。

我想我在找人確認(或相反)。

__Second更新:__

因爲沒有人真正地回答了這個問題我沒有選擇的答案。我會放開它,希望有人可能會提供我所尋求的信息。

__Third Update__

仍住在(微弱)的希望。

__Fourth Update__

嗯,我從來沒有得到一個可用的答案。當我問這個問題時,我已經完成了我正在寫的模塊。我認爲這個問題是出於實際目的而死的。我可能不會再更新。

+0

Windows不會自動放大堆棧。 – Christopher 2010-06-17 10:06:57

+0

克里斯托弗 - 是的。閱讀我鏈接到的Raymond Chen曲目。 – 2010-06-17 17:15:10

回答

0

根據MSDN

線程訪問的存儲器與PAGE_GUARD修改分配 。

這聽起來像不應該發生的事情,除非你有一個bug;所以我會相應地處理它。

編輯

操作系統異常處理你之前被註冊,所以在處理它自己並不意味着OS沒能第一眼看到它。

+3

堆棧中的最後一頁具有GUARD PAGE屬性。當你訪問它時,它會產生一個異常來警告操作系統放大堆棧。至少,在內核模式下會發生這種情況。不確定它如何在用戶空間中工作。 – 2010-06-17 02:38:11

3

使用VirtualProtectEx()設置頁面以生成STATUS_GUARD_PAGE_VIOLATION並且PAGE_GUARD標誌是documented procedure。這個異常只能爲頁面生成一次,所以在處理異常時不會有任何危險。

我不會爲異常做任何特殊的事情,但這並不能證明太多,得到這個例外將是非常罕見的。在我們的任何崩潰報告中從未見過它。

該功能真正用於生成堆棧溢出異常。你真的需要特別處理,因爲你剩下的堆棧很少。我認爲這是你在問題中提到的警告。然而,它將永遠不會產生一個頁面防護異常,它在內核級別處理之後纔會被轉換爲堆棧溢出。

+0

實際上,在內核模式下,你需要*不處理它。你讓它通過操作系統,它擴大了堆棧。如果你抓住它,操作系統不會看到它,堆棧也不會被放大,併發生堆棧溢出。我的問題是它是否可以在用戶模式下生成。我的猜測是「不」,但我正在尋求確認。 – 2010-11-18 13:19:22

+0

提問並回答:「然而它永遠不會生成頁面防護例外,這是在內核級別處理的」。 – 2010-11-18 13:40:33

1

根據我對virtualquery的觀察,它類似於內核模式的情況。如果訪問的防護頁堆棧不屬於訪問線程,則調試器可以捕獲該異常。無論如何,你應該已經有了答案。

+0

你能解釋一點嗎?我不太清楚你的意思。您可能可以弄清楚某個特定頁面是否具有「guard page」屬性,但是如何使用VirtualQuery()檢測其異常行爲?我沒有看到在用戶模式下拋出EXCEPTION_GUARD_PAGE異常,但我可能沒有成功地耗盡堆棧內存來觸發一個。 – 2012-08-08 18:34:27