1

我有一个奇怪的情况。我的游戏肯定是用调试信息构建的,我可以愉快地打断点和单步执行代码,并查看数据。没有设置异常。我已经排除了多线程问题。当我有一个实际的错误和一个合法的崩溃时,我没有得到调用堆栈。一个典型的崩溃错误将是

First-chance exception at 0x004678da in Democracy3Debug.exe: 0xC0000005: Access violation reading location 0x0000004c.
Unhandled exception at 0x774015de in Democracy3Debug.exe: 0xC0000005: Access violation reading location 0x0000004c.

调用堆栈只是 ntdll 和一些反汇编。我一定在某处改变了一些选项,但无法想象是什么。有任何想法吗?

4

2 回答 2

1

这些错误表示硬件异常,因为您尝试访问您的进程无法读取或写入的内存。特别是,您似乎直接或间接地尝试从某个指针所指的地址访问某个元素的 76 字节,但该指针实际上为空(因此访问冲突读取位置 0x0000004c)。

您的调试信息可能不会以任何方式无效,您可能只是合法地位于 nt.dll 内的某些代码中——例如,如果您将空指针传递给不允许它们的 Windows API 函数。如果您没有为 nt.dll 加载符号,您将不会获得有用的调用堆栈。

访问冲突也可能来自您传递的错误指针,该指针在 Windows API 调用某些回调之前未使用,这可能解释了为什么您在堆栈帧中的任何地方都看不到代码。

在 VS IDE 中启用 break-on-throw(调试 -> 异常,选中相关异常类型的复选框)可以帮助您在发生这种情况时更早地中断,但如果问题不是直接来自您的代码,则可能无助于诊断问题。

您还可以使用结构化异常处理来集成这些异常和 C++ 的异常以进行捕获。您可能还想研究使用符号服务器来获取 Windows DLL 的符号。

于 2013-02-25T17:25:56.117 回答
0

您的异常没有被捕获,因此它将调用堆栈一直向上移动到 main 并终止您的应用程序。

MSDN:

如果找不到当前异常的匹配处理程序(或省略号捕获处理程序),则调用预定义的终止运行时函数。

通常有一个选项允许您在抛出异常时暂停调试。

如何:抛出异常时中断 (Visual Studio 2012)

您还可以在顶层有一个 catch 语句,并在捕获异常时检查异常(.what() 通常给出描述)。

更新:您很可能无法捕获此异常,因为它是访问冲突(不是 C++ 异常,但暂停应该仍然有效)。如果你在 Windows 上,你可以使用 SEH 来捕捉它。

于 2013-02-25T16:45:07.320 回答