我从2年前开始编程游戏。 有时一些内存错误(即:一个返回垃圾而不是它应该返回的函数,或者只发生在Linux上的崩溃,而且从未发生过GDB或Windows的崩溃)似乎随机发生。也就是说,我尝试修复它,几个月后相同的错误再次困扰着我。
有一个软件(不是Valgrind,我已经尝试过了......它找不到错误)可以帮我解决这个问题吗?或者解决这些错误的方法?我想永久修复它们。
答案 0 :(得分:3)
在Windows上,您可以自动捕获生产环境中的崩溃异常并对其进行分析,就像在调试器下的开发者PC上发生错误一样。这是使用“迷你转储”文件完成的。您基本上使用Windows“dbghelp.dll”DLL来生成线程堆栈,部分或全部堆,寄存器值,加载的模块以及导致崩溃的未处理异常的副本。您可以在MS Visual Studio调试器中启动此“.dmp”文件,就像它是可执行文件一样,它将显示崩溃发生的确切位置。
您可以设置trap for unhandled exceptions并将小型转储文件的创建委派给该陷阱中的dbghelp.dll。您需要保留使用已部署的二进制文件生成的“.pdb”文件,以使内存地址与源代码位置相匹配,以获得更好的调试体验。此主题太深,无法完全覆盖此DLL上的Microsoft's documentation。
您需要能够将.dmp文件从崩溃的PC复制到开发环境中,以便对其进行全面调试。如果您与用户之间存在不干涉关系,则需要选择通过互联网使用单独的实用程序应用程序“phone home”将.dmp文件传输到您可以访问它的位置。生成.dmp文件后,您可以从未处理的异常陷阱启动应用程序。对于用户隐私,您应该为用户提供是否执行此操作的选项。
答案 1 :(得分:1)
Totalview调试器(商业软件)可能会发现崩溃。
Purify(商业软件)可以帮助您发现内存泄漏。
您的代码是否编译无编译器警告?你有没有运行lint?
答案 2 :(得分:1)
您可以尝试的一件事是将Hans Boehm GC与您的项目一起使用。它可以用作泄漏检测器,允许您删除可疑的free()
或delete
语句,并轻松查看它们是否会导致内存泄漏。
答案 3 :(得分:0)
AFAIK,Windows中的Boundscheck表现非常出色。在我的一个项目中,它发现了一些非常奇怪的错误。
答案 4 :(得分:0)
为了避免在我自己的项目中(在Windows上),我编写了自己的内存分配器,它简单地称为VirtualAlloc和VirtualFree。它为每个请求分配了一个额外的页面,将其对齐到最后一页的左侧,并在访问最后一页时使用VirtualProtect
生成异常。这检测到越界访问,甚至只是在现场读取。
免责声明:我绝不是第一个有这个想法的人。
例如,如果页面是4096字节,并且调用了new int[1]
,则分配器将:
以下代码:
main() {
int *array = new int[10];
return array[10];
}
然后会在现场产生访问冲突。
它还有一个(编译时)选项来检测分配的 left 侧之外的访问(即数组[-1]),但这些错误似乎很少见,所以我从未使用过该选项。