0

这与我之前的问题有关; 向量和堆栈溢出

但希望能解释新情况(和我的新问题)。所以昨天我以为我在这个堆栈溢出异常中有一个突破,我以为我已经解决了。虽然那时我很累,并且注释掉了很多代码。

今天早上,重新开始我的游戏,我首先让一切恢复运行。就在大约半小时前,我绝望地看到了我以为我昨天已经克服的血腥错误消息:/。

唉,我回到了第一方,但继续回答我之前的问题,我再次试图找到我认为是敌人动画的根本原因。下面是我的敌人和动画类的头文件:

动画 - http://pastebin.com/uKQB1RVq

敌人 - http://pastebin.com/pktA1vXi

正如您在我的敌人课程中看到的那样,除了动画之外,没有什么值得谈论的,我觉得会导致这个异常。(唯一的另一件事是我的 Timer 类,它只是一些 int 和 bool,同样没有什么我可以认为是内存广泛的。)

所以我的问题是这样的;

  1. 我怎么能对此百分百肯定呢?我的 IDE (Visual C++ 2010) 中有没有办法查看正在使用多少堆栈内存?
  2. 从 q 开始。1,这个问题的解决方案是什么,例如,即使我不能 100% 确定动画是异常的实际原因,但将动画注释掉并说创建动画矢量编译没有问题。那是要走的路吗?

*我已经设置了测试场景,我知道如果我将 Vector2 和 RectArray 的数组减少到 15 而不是 20 则使用普通的旧 4 动画调用(只是说这些是简单的结构,包含普通旧 x 的整数& y,然后对于 x、y、宽度和高度)游戏编译得很好(这很可能是我倾向于 Animation 类的主要原因),如果我可以测量它有多少堆栈内存正在使用,然后将其与创建动画矢量数组所使用的进行比较,那么我希望能够很好地判断这是否是更重要的真正问题,或者它是否实际上是其他问题。

编辑:所以进一步研究我的溢出,我正在研究我的游戏的反汇编信息。堆栈溢出特定指向发生溢出的特定地址; 0xC0000005

搜索那个地址,我看到我来到了这个视图; 在此处输入图像描述

我真的不知道如何处理这些地址中的内容,当我将鼠标悬停在它上面时,我得到的只是一个非常大的数字。我只能说有很多这样的“???” 但我想这些可能意味着什么。

4

1 回答 1

1

正如您在上一篇文章的回答中提到的,基本上有三种方法可以得到 Stack Overflow 错误。

  1. 无限递归。这很容易确定 - 只需检查所有递归函数,它们是否正常工作并且在某些情况下总是会终止。

  2. 在堆栈上分配巨大的变量。这实际上与第一个问题有关 - 递归堆栈溢出发生,因为堆栈上没有空间用于另一个递归调用的局部变量。这也很容易确定 - 您必须使用许多(或很少,但很大)静态分配的数组(在编译时已知大小)或结构来导致问题。

  3. 缓冲区溢出。这是要追查的最糟糕的噩梦,因为实际问题可能在其原因发生很久之后才发生。

我建议尝试通过以下方式确定问题。

  • 在问题仍然存在时,尽可能多地注释掉代码。如果幸运的话,您将注释掉实际上导致问题的地方。否则你将有更少的代码来分析。
  • 使用 WinDbg(在平台 SDK 中提供)获取崩溃时的详细调用堆栈。您可以在系统注册表中添加以下条目,以强制操作系统将部分或全部进程内存转储收集到文件中,以便您可以尝试执行事后分析:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\YourAppName.exe] "DumpFolder"=hex(2):63,00,3a,00,5c,00,44,00,75,00,6d,00,70,00,73,00,00,00 "DumpType"=dword:00000002 "DumpCount"=dword:0000000F

每次应用程序崩溃时,此更改都会将完整转储到 ac:\dumps 文件夹。

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\YourAppName.exe] "DumpFolder"=hex(2):63,00,3a,00,5c,00,44,00,75,00,6d,00,70,00,73,00,00,00 "DumpType"=dword:00000001 "DumpCount"=dword:000000FF

每次应用程序崩溃时,此更改都会将小转储 (~40 Mb) 转储到 ac:\dumps 文件夹。

  • 使用 Application Verifier 工具来跟踪潜在的缓冲区溢出,这可能会损坏存储在堆栈中的返回地址。

  • 为你的结构和类的一些重要领域添加警卫,即:

const char * sentry1 = "0123456789";
void * vitalField;
const char * sentry2 = "0123456789";

尤其是在类、结构和方法的开头和结尾处使用它们。使用调试模式确保优化器不会优化它们(因为未使用)。

崩溃后,收集内存转储并尝试检查,如果你所有的守卫都保持不变(这可能很困难,但并非不可能)。

  • 最后,您可以进行非常详细的代码审查,以确保不会发生缓冲区溢出。


编辑:

您可以通过以下方式使 WinDbg 转储测试更加自动化:

  • 设置以下环境变量:

_NT_SYMBOL_PATH=symsrv*symsrv.dll*c:\symbols*http://msdl.microsoft.com/download/symbols

它将被 WinDbg、Visual Studio 和 Process Explorer 使用

  • 在 WinDbg 目录中创建以下文件:

命令.txt

.sympath+.
.reload
kb

  • 将以下条目添加到您的注册表中(检查您的系统是 32 位还是 64 位,并在必要时进行更改):

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT.dmp] @="Debugger.Dump"

[HKEY_CLASSES_ROOT\Debugger.Dump]

[HKEY_CLASSES_ROOT\Debugger.Dump\Shell]

[HKEY_CLASSES_ROOT\Debugger.Dump\Shell\Debug_Without_Remote] @="WinDbg This Dump"

[HKEY_CLASSES_ROOT\Debugger.Dump\Shell\Debug_Without_Remote\Command] @="\"C:\Program Files\Debugging Tools for Windows (x64)\windbg\" -z \"%1\" -QY -c \"$<C:\Program Files\Debugging Tools for Windows (x64)\commands.txt\""

祝你好运 :)

于 2012-07-24T10:19:38.480 回答