如何调试堆损坏错误? [英] How to debug heap corruption errors?

查看:206
本文介绍了如何调试堆损坏错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Visual Studio 2008下调试(本机)多线程C ++应用程序。在看似随机的场合,我得到一个Windows已经触发了一个断点...错误,注意到这可能是由于堆中的损坏。这些错误并不总是会立即崩溃应用程序,尽管它可能会在短时间内崩溃。



这些错误的大问题是它们只在后腐败实际上发生了,这使得他们很难跟踪和调试,特别是在多线程应用程序上。




  • 什么


  • 如何调试?




欢迎提示,工具,方法,启发...

解决方案

应用程序验证程序适用于Windows的调试工具是一个了不起的设置。您可以将这两者都作为 Windows驱动程序工具包或更轻的Windows SDK 。 (在研究)我曾经使用过BoundsChecker和Insure ++(在其他答案中提到),尽管我对Application Verifier中有多少功能感到惊讶。 p>

电动围栏(又名efence), dmalloc valgrind 等等都值得一提,但是大多数这些都比Windows更容易在* nix下运行。 Valgrind是非常灵活的:我已经调试大型服务器软件与许多堆问题使用它。



当所有其他失败,你可以提供自己的全局运算符新/删除和malloc / calloc / realloc重载 - 如何做到这一点会有所不同,这取决于编译器和平台 - 这将是一个投资 - 但它可能会从长远的回报。理想的功能列表应该看起来很熟悉dmalloc和电力,而令人惊讶的优秀的书籍编写固定代码




  • 哨兵值:在每个分配之前和之后允许一点空间,符合最大对齐要求;填充魔术数字(有助于捕获缓冲区溢出和下溢以及偶尔的野生指针)

  • alloc fill :使用魔术非0填充新的分配价值 - Visual C ++已经在Debug构建中为您做了这个(有助于捕获未初始化的vars)

  • 免费填充:用魔法填充释放的内存非0值,旨在触发segfault,如果在大多数情况下解除引用(有助于捕获悬挂指针)

  • 延迟免费:不要将释放的内存返回堆一段时间,保持空闲,但不可用(有助于捕获更多的悬挂指针,抓住双重释放)

  • 跟踪:能够记录有时分配是有用的



请注意,在我们的本地自制软件系统(嵌入式目标)中,我们保持跟踪分离从大多数其他的东西,因为运行时间开销要高得多。






如果您有更多的理由来重载这些分配函数/运算符,请查看我的答案是任何超载全球运营商新增和删除的原因;无耻的自我宣传除外,它列出了有助于跟踪堆损坏错误的其他技术,以及其他适用的工具。


I am debugging a (native) multi-threaded C++ application under Visual Studio 2008. On seemingly random occasions, I get a "Windows has triggered a break point..." error with a note that this might be due to a corruption in the heap. These errors won't always crash the application right away, although it is likely to crash short after.

The big problem with these errors is that they pop up only after the corruption has actually taken place, which makes them very hard to track and debug, especially on a multi-threaded application.

  • What sort of things can cause these errors?

  • How do I debug them?

Tips, tools, methods, enlightments... are welcome.

解决方案

Application Verifier combined with Debugging Tools for Windows is an amazing setup. You can get both as a part of the Windows Driver Kit or the lighter Windows SDK. (Found out about Application Verifier when researching an earlier question about a heap corruption issue.) I've used BoundsChecker and Insure++ (mentioned in other answers) in the past too, although I was surprised how much functionality was in Application Verifier.

Electric Fence (aka "efence"), dmalloc, valgrind, and so forth are all worth mentioning, but most of these are much easier to get running under *nix than Windows. Valgrind is ridiculously flexible: I've debugged large server software with many heap issues using it.

When all else fails, you can provide your own global operator new/delete and malloc/calloc/realloc overloads -- how to do so will vary a bit depending on compiler and platform -- and this will be a bit of an investment -- but it may pay off over the long run. The desirable feature list should look familiar from dmalloc and electricfence, and the surprisingly excellent book Writing Solid Code:

  • sentry values: allow a little more space before and after each alloc, respecting maximum alignment requirement; fill with magic numbers (helps catch buffer overflows and underflows, and the occasional "wild" pointer)
  • alloc fill: fill new allocations with a magic non-0 value -- Visual C++ will already do this for you in Debug builds (helps catch use of uninitialized vars)
  • free fill: fill in freed memory with a magic non-0 value, designed to trigger a segfault if it's dereferenced in most cases (helps catch dangling pointers)
  • delayed free: don't return freed memory to the heap for a while, keep it free filled but not available (helps catch more dangling pointers, catches proximate double-frees)
  • tracking: being able to record where an allocation was made can sometimes be useful

Note that in our local homebrew system (for an embedded target) we keep the tracking separate from most of the other stuff, because the run-time overhead is much higher.


If you're interested in more reasons to overload these allocation functions/operators, take a look at my answer to "Any reason to overload global operator new and delete?"; shameless self-promotion aside, it lists other techniques that are helpful in tracking heap corruption errors, as well as other applicable tools.

这篇关于如何调试堆损坏错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆