簡體   English   中英

使用調用堆棧進行C ++ Visual Studio調試

[英]C++ Visual Studio debugging with call stack

我最近開始學習來自C#背景的C ++。 我的問題是處理異常的方式。

如果我在某處有一個nullptr ,導致從禁止的位置讀取,那么我在VS中得到一個漂亮的callstack,如下所示:

調用堆棧

但是,如果我拋出自己的異常,或者斷言失敗,那么我就不知道出了什么問題。 VS只顯示一個錯誤窗口:

在此輸入圖像描述

答:這對我來說有點不舒服,因為在C#中我會得到一個堆棧跟蹤。 有沒有辦法打印堆棧跟蹤? 或者是否有任何VS的插件來實現此功能?

B:為什么AccessViolationException與我們自己拋出的異常不同? 為什么我們沒有斷言失敗的堆棧跟蹤?

C:創建自己的斷言函數有多糟糕,當斷言失敗時會導致AccessViolationException?

編輯1:是的,我應該仔細閱讀消息框,而不是立即點擊中止。 我的錯。

為什么AccessViolationException與我們自己拋出的異常不同?

因為AV是特殊的,所以它是由處理器本身觸發的異常。 當它發出不再能夠執行代碼的信號時引發。 這就像你可能想象的那樣糟糕。 從AV中恢復是非常非常困難的,並且通常不應該嘗試。 你不能再對你的程序狀態進行推理了,你不知道它只是在一個原始的指令地址之外死了。

從技術上講,捕獲和處理AV是必要的,您必須使用結構化異常處理。 它需要在MSVC ++中使用非標准的__try和__except關鍵字。 但是您不應該這樣做,因為處理異常需要您還將程序狀態恢復到運行失敗代碼之前的狀態。 無法可靠地執行,因為您無法再解釋該狀態,您不知道異常跳過了哪些代碼。

您可以以一種合理的方式使程序關閉,它需要使用SetUnhandledExceptionFilter()winapi函數。 相當於C#中的AppDomain.UnhandledException。 所有這些當然都是完全非標准的C ++。 C ++標准規定,符合標准的C ++程序永遠不應該調用未定義的行為,並且不指定當你做什么時應該發生什么。

否則這是靠近金屬編程的直接結果。 托管代碼中有很多反措施可以防止程序進入這樣的狀態。 這些反措施不是免費的,本機C ++關心的是盡可能快地運行代碼。 失去診斷是這種權衡的一部分。 不要調用未定義的行為。

暫無
暫無

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

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