使用未执行的代码崩溃

crash with unexecuted code

本文关键字:代码 崩溃 执行      更新时间:2023-10-16

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

几乎从零开始,我使用了一个插件示例代码,在其中我逐渐添加了我的代码。我的插件添加了一个按钮来创建我的工具。该工具和按钮是两个独立的COM对象。按钮总是被创建的,但只有当我按下按钮时,工具对象才会被创建。现在,我在工具部分添加了一些代码,代码没有执行,工具对象甚至没有创建,但程序崩溃了。如果没有这部分代码,它就不会。它似乎不依赖于代码的这一部分,当我对它进行注释并在其他地方添加一些代码(这些代码不会被执行)时,程序也会以同样的方式崩溃。

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

我有什么想法或调试策略可以开始吗?

谢谢。

给出代码示例总是有帮助的。

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

无法连接的崩溃可能是由静态初始化引起的。当你的DLL被附加时,我会尝试手动初始化这些类型的资源。在分离DLL时删除资源,并将指针设置为零。拥有可以处理此问题的"主要"静态函数。

您还可能对statics的初始化顺序进行假设,这一点也不能保证。更糟糕的是,它们会在很长一段时间内表现得相对一致,然后由于一些根本不明显的原因在看似随机的时间断裂。

COM对象的另一种可能性是,二进制兼容性与调用代码所期望的接口不再匹配。如果您正在实现的接口不是纯虚拟的,这可能会特别出乎意料。如果接口有任何具有默认实现的方法,则需要重写它们。

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();
  }
};

我个人从来没有看到过堆损坏消息,但我看到过它用垃圾指针调用方法。我可以看到,如果你试图释放它,可能会在哪里被检测为堆损坏。