繁体   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