如何调试堆损坏错误?
我在Visual Studio 2008下调试了一个(本机)多线程C ++应用程序。在看似偶然的场合,我得到一个“Windows引发了一个断点...”的错误,并注意到这可能是由于堆。 这些错误不会总是使应用程序崩溃,尽管它很可能会在短期内崩溃。
这些错误的主要问题是,只有在腐败实际发生后才会弹出,这使得他们很难跟踪和调试,特别是在多线程应用程序上。
什么样的事情会导致这些错误?
我如何调试它们?
提示,工具,方法,启示...是受欢迎的。
应用程序验证程序结合Windows调试工具是一个了不起的设置。 您可以将它们作为Windows Driver Kit或更轻的Windows SDK的一部分。 (在研究关于堆损坏问题的早期问题时,发现了Application Verifier。)我在过去也使用过BoundsChecker和Insure ++(在其他答案中提到过),尽管我很惊讶Application Verifier中有多少功能。
电篱笆(又名“efence”),dmalloc,valgrind等都值得一提,但其中大多数在* nix下运行比Windows更容易。 Valgrind是非常灵活的:我用大量的堆问题调试了大型服务器软件。
当所有其他的失败时,你可以提供你自己的全局运算符new / delete和malloc / calloc / realloc重载 - 如何做到这一点将取决于编译器和平台而有所不同 - 这将是一个投资 - 但从长远来看它可能会有所回报。 理想的功能列表看起来应该与dmalloc和电子栏目相似,并且出色的优秀书写固体代码:
请注意,在我们的本地自制系统中(对于嵌入式目标),我们将跟踪与大部分其他内容分开,因为运行时开销要高得多。
如果您有更多理由来重载这些分配函数/操作符,请查看我对“重载全局操作符new和delete”的任何理由的回答。 无耻的自我推销,它列出了其他技术,有助于跟踪堆损坏错误,以及其他适用的工具。
您可以通过为应用程序启用Page Heap来检测大量堆损坏问题。 为此,您需要使用作为Windows调试工具的一部分的gflags.exe
运行Gflags.exe并在可执行文件的映像文件选项中,选中“启用页面堆”选项。
现在重新启动您的exe并附加到调试器。 启用页面堆时,每当发生任何堆损坏时,应用程序都会进入调试器。
一篇非常相关的文章是使用Application Verifier和Debugdiag调试堆损坏。
链接地址: http://www.djcxy.com/p/2327.html