【问题标题】:Debugging crashes due to base class size change由于基类大小更改而导致调试崩溃
【发布时间】:2011-12-23 15:32:44
【问题描述】:

最近,由于基类和派生类的类大小更改未编译,我遇到了几次崩溃。让我举一个简单的例子。我有一个基类,Base.dll 中存在“BaseClass”,我继承了该类并创建了 DerivedClass,它存在于 Derived.dll 中。每当 BaseClass 大小更改时,应重新编译 Derived.dll。但是可能并不总是可以找到所有依赖二进制文件,有时人们会错过一些依赖二进制文件。在这些情况下,我们会遇到难以调试的神秘崩溃。有没有办法缩小这些问题的范围?也就是说,有哪些线索会让你往这个方向思考?

编辑 1:更多细节。请假设有多个基类,例如 base1、base2、base3 等,每个都派生在单独的 dll 中。派生1.dll、派生2.dll和派生3.dll。没有必要为一个基类中的大小变化编译所有其他项目。此外,建立依赖关系不是一种选择,这就是我们经常遇到这个问题的原因。

【问题讨论】:

  • BaseClass 定义的更改应该会触发DerivedClass 及其依赖项的重新编译。为什么没有发生这种情况?

标签: c++ visual-c++ dll


【解决方案1】:

方法一是修复依赖关系,以便正确重新编译所有依赖模块。跨共享库可能会很麻烦,但看看是否不能直接修复。

方法二是始终“全部重建”。或者总是删除 obj 目录中的所有内容并构建。

方法三是添加一些调试模式代码,用于检查对象的大小并将它们与跨 API 边界的新调用进行比较,API 边界返回对象的大小。

【讨论】:

    【解决方案2】:

    除了重新编译之外,没有万无一失的选择。如果查找从您的class BaseClass 派生的类是一个问题,那么可以通过以下方式解决。

    class FinalLock {
      FinalLock () {}
      friend class BaseClass;
    };
    

    每当您更改 BaseClass 大小时,请执行以下操作:

    class BaseClass : virtual FinalLock {
      ...
    };
    

    然后重新编译整个项目。无论从BaseClass派生的类都会导致编译器错误(实际上,类的实例化会导致错误)。

    这会告诉您哪些类依赖于BaseClass。这个练习只需要一次。然后你可以标记所有的依赖代码。

    完成后删除此额外代码。使用 C++11,上述技术可以变得更加简单:

    final class BaseClass {
    ^^^^^
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-03
      • 2012-02-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-15
      • 1970-01-01
      • 2018-04-18
      相关资源
      最近更新 更多