![](/img/trans.png)
[英]C++ Getters and Setters alternatives for Call Stack on 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.