【问题标题】:How to determine who delete a heap object如何确定谁删除了一个堆对象
【发布时间】:2018-07-25 16:38:17
【问题描述】:

我们的软件应用程序在客户的系统上随机崩溃。坏事是我们无法重现我们这边的崩溃。客户向我们发送了日志文件和转储文件,通过分析我们认为崩溃是由某些堆对象的过早删除引起的。但是我们无法找到这些堆对象被删除的位置。我的问题是是否有办法确定哪个函数删除了一个堆对象。由于我们可能需要在客户的系统上运行它,因此该解决方案不应过多地降低效率。

应用程序是用原生 C++ 编写并在 Windows 7 中运行。堆对象被包装在智能指针中,并由多个线程创建和使用。

【问题讨论】:

  • 我想知道如果您使用智能指针,您是如何结束过早删除的? (如果您还没有这样做,我要做的第一件事是 grep 关键字delete 的所有源代码,并确保没有人做错了(tm)。即在使用智能指针的应用程序中delete 关键字不应出现在任何地方)
  • 请阅读stackoverflow.com/help/how-to-ask。我们需要更多信息来帮助您。
  • 请注意,如果您的代码库中的某个地方有人/某物正在写入无效/未分配的内存地址并设法覆盖一些堆的元数据,从而破坏堆,则您可能会遇到类似的崩溃而不会过早删除。 valgrind 通常是您追踪此类损害的朋友...
  • 我想对@JeremyFriesner 所说的添加一些内容。在所有者线程释放该对象之后,线程可能会写入该对象。
  • @Jeremy Friesner 这些类的析构函数都受到保护。

标签: c++ multithreading debugging heap-memory heap-corruption


【解决方案1】:

我的问题是是否有办法确定哪个函数删除了一个堆对象。

您不是编写应用程序的团队吗?你应该知道哪些函数做了什么,如果你不阅读文档,如果没有,则阅读代码。

现在手续已经不碍事了,我很同情。像这样的事件可能很难诊断,特别是考虑到可能需要在客户系统上进行复制的敏感性。第一步是将转储文件加载到调试器中并彻底检查系统状态。您最好的开发人员将需要寻找意外的线索,这些线索会在他们的蜥蜴大脑中触发“尤里卡”时刻,从而将他们指向一些意想不到的系统状态,但他们仍然认为这些状态是遥不可及的。如果这没有发生,你就是 SOL tbh。

Jeremy 在上面也给出了一些好主意。绝不保证现在运行 valgrind 会发现问题,但如果您的代码库中存在系统性问题,那么对 valgrind 进行彻底的测试运行可能会发现问题。凭借运气和人类启发式方法,您可能能够自信地确定问题是导致客户崩溃的原因。但是...作为发布检查的一部分,您已经在进行 valgrind 测试,对吧...?

还有什么……嗯……嗯,你问的是关于追踪的问题。您不能只拨动开关来获得您想要的 - 您必须在应用程序中创建然后激活一些高度冗长的调试模式,这必然会影响性能,并且如果问题像它一样罕见/意外听起来,你可能需要运行这个东西几个月。可能不太可行。

最后,为了覆盖所有基础,通过静态分析器运行您的代码(同样,如果您还没有这样做的话)以检查真正明显的错误。不要对此抱有太大期望,但当某人一直在写代码时,它有时会导致快速获胜。 CppCheck 有它的时刻(虽然说实话,它也可能有点像丁丁)。

祝你好运!

【讨论】:

  • 我不是设计和实现这个应用程序的程序员之一。这是制造自动化的一个相当复杂的应用。查看代码对我没有多大帮助。我做了静态代码分析,发现了一些问题。在我们修复了这些问题后,应用程序看起来更稳定了,但仍然崩溃。
  • @user3552888:这些程序员还在你的公司工作吗?
猜你喜欢
  • 2013-05-10
  • 2011-10-14
  • 2013-03-05
  • 1970-01-01
  • 2010-12-15
  • 2016-01-31
  • 2015-04-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多