与未执行的代码崩溃

时间:2012-03-13 15:50:44

标签: c++ debugging com heap

我正在调试商业软件的插件。应用程序在按下退出按钮后崩溃。这些崩溃出现在windows vista 64 sp2或vista 32上(不记得是否sp)但不在windows xp sp3上。根据应用程序生成的崩溃日志,看起来我有一些堆问题,所以我调试了页面堆激活。

几乎从头开始,我拿了一个插件示例代码,我逐渐添加我的代码。我的插件添加了一个创建我的工具的按钮。工具和按钮是两个单独的COM对象。始终创建按钮,但仅当我按下按钮时才会创建工具对象。 现在,我在工具部分添加了一些代码,代码未执行,甚至没有创建工具对象,但程序崩溃了。如果没有这部分代码,它就没有。它似乎不依赖于代码的那一部分,当我评论它并在其他地方添加一些代码(不会被执行)时,程序以同样的方式崩溃。

adplus告诉我:损坏的堆指针或使用错误的堆 xx:呼叫中使用的堆 xx:堆块 xx:块大小 xx:堆拥有块

我可以从哪个想法或调试策略开始?

感谢。

1 个答案:

答案 0 :(得分:0)

提供代码示例总是有帮助的。

堆损坏非常棘手,因为即使它是错误的,也可能无法检测到。因此,虽然您可能会以某种方式持续崩溃,但这并不意味着当您没有崩溃时它不会被破坏。

由于静态初始化,可能会导致无法连接崩溃。我会尝试在附加DLL时手动初始化这些类型的资源。分离DLL时删除资源,并将指针设置为零。拥有处理此功能的“主要”静态功能,您可以介入。

您可能也会对静态的初始化顺序做出假设,但这并不能保证。更糟糕的是,他们会在很长一段时间内表现得相对一致,然后因为某种原因而在一个看似随机的时间突破,这一点并不明显。

COM对象的另一种可能性是您的二进制兼容性不再与调用代码所期望的接口匹配。如果您正在实现的界面不是PURE虚拟,那么这可能是特别意外的。如果接口具有任何具有默认实现的方法,则需要覆盖它们。

struct foo_base {
  virtual ~foo_base() {}
  virtual std::string getName() const {
    return "Willem Dafoe";
  }
};

struct foo_derived : public foo_base {
  virtual ~foo_derived() {}
};

即使这是完全有效的C ++,它也可能无法用作COM对象。

如果您对血腥细节不感兴趣,请为刚刚调用基础的虚拟方法添加实现。

struct foo_base {
  virtual ~foo_base() {}
  virtual std::string getName() const {
    return "Willem Dafoe";
  }
};

struct foo_derived : public foo_base {
  virtual ~foo_derived() {}
  virtual std::string getName() const {
    return foo_base::getName();
  }
};

我个人从未见过堆损坏消息,但我看到它用垃圾指针调用方法。如果你试图释放它,我可以看到可能被检测为堆损坏的位置。