簡體   English   中英

為什么我的代碼不會在Windows 7上出現段錯誤?

[英]Why won't my code segfault on Windows 7?

這是一個不尋常的問題,但這里有:

在我的代碼中,我意外地在某處取消引用NULL。 但是,不是使用segfault崩潰的應用程序,它似乎停止執行當前函數並將控制權返回給UI。 這使調試變得困難,因為我通常希望收到崩潰警報,以便我可以附加調試器。

可能是什么導致了這個?

具體來說,我的代碼是ODBC驅動程序(即DLL)。 我的測試應用程序是ODBC測試(odbct32w.exe),它允許我在我的DLL中顯式調用ODBC API函數。 當我調用其中一個已知段錯誤的函數時,ODBC測試只是將控制權返回給UI而不打印函數調用的結果。 然后我可以再次調用我的驅動程序中的任何函數。

我確實知道技術上應用程序調用ODBC驅動程序管理器,它加載並調用我的驅動程序中的函數。 但是,由於我的段錯誤(或正在發生的任何事情)導致驅動程序管理器功能也不返回(由應用程序不打印結果證明),這就是重點。

我的一個有類似機器的同事遇到了同樣的問題而另一個沒有,但是我們無法確定任何具體的差異。

Windows具有非可移植語言擴展(稱為“SEH”) ,允許您將頁面錯誤和分段違規作為異常進行捕獲。

操作系統庫的某些部分(特別是在操作系統代碼中處理一些窗口消息,如果我沒記錯的話)有一個__try塊,即使面對這樣的災難性錯誤,也會使代碼繼續運行。 可能你被稱為這些__try塊中的一個。 傷心但真實。

查看此博客文章,例如: 消失的OnLoad異常的情況 - x64中的用戶模式回調異常

更新:

我發現在評論中歸因於我的那種想法有點奇怪。 作為記錄:

  • 我並沒有聲稱自己SEH是壞的。

    我說這是“非便攜式”,這是事實。 我還聲稱使用SEH忽略用戶模式代碼中的STATUS_ACCESS_VIOLATION是“悲傷”。 我支持這個。 我希望我有勇氣在新代碼中執行此操作,並且您正在查看我會對我大喊大叫的代碼,就好像我寫了catch (...) { /* Ignore this! */ } catch (...) { /* Ignore this! */ } 這是個壞主意。 這對於訪問沖突尤其不利,因為獲取AV通常意味着您的進程處於錯誤狀態,並且您不應該繼續執行。

  • 並不認為SEH的存在意味着你必須吞下所有的錯誤。

    當然,SEH是一種通用機制,並不是每次愚蠢使用它的原因。 我所說的是,一些Windows二進制文件在調用函數指針時會吞下STATUS_ACCESS_VIOLATION ,這是一個真實且可觀察的事實,並且這不是很漂亮。 請注意,他們可能有歷史原因或情有可原的情況來證明這一點。 因此“悲傷而真實”。

  • 我這里沒有注入任何“Windows與Unix的”豪言壯語。 在任何平台上,一個壞主意都是個壞主意。 試圖在Unix類型的操作系統上從SIGSEGV恢復也同樣粗略。

解除引用NULL指針是一種未定義的行為,它幾乎可以產生任何東西 - 一個seg.fault,一個寫入IRS的信,或一個發布到stackoverflow :)

在這里閱讀不同類型的異常處理程序 - 它們沒有捕獲相同類型的異常。

Windows 7也有它的Fault Tollerant Heap(FTH),它有時會做這些事情。 在我的情況下,它也是一個NULL-dereference。 如果你在Windows 7上開發,你真的想要關閉它!

什么是Windows 7的容錯堆?

http://msdn.microsoft.com/en-us/library/dd744764%28v=vs.85%29.aspx

將調試器附加到可能調用您的dll的所有應用程序,在[debug] | [exceptions]菜單中拋出不僅未處理的摘要時打開要中斷的功能。

ODBC是大多數(如果不是全部)COM,因為這樣的未處理異常會導致問題,這可能會出現奇怪的退出ODBC函數或者掛起並且永遠不會返回的錯誤。

暫無
暫無

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

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