【问题标题】:MinGW 4.7.0 to 4.7.2 bug: Invalid "this" pointer in member functions when using mixed virtual and non-virtual multiple inheritanceMinGW 4.7.0 到 4.7.2 错误:使用混合虚拟和非虚拟多重继承时,成员函数中的“this”指针无效
【发布时间】:2013-09-29 03:04:22
【问题描述】:

我的继承代码如下所示:

        B
       / \
      /   \
     /     \
    BI      D
(template) /
      \   /
       \ /
        DI
    (template)

[B]ase[D]erived 是两个包含static 方法create() 的接口,该方法返回各自实现的实例BaseImplDerivedImpl。 实现是模板,工厂方法选择如何在运行时实例化它们。下面的代码是我的程序逻辑的一个工作示例。

问题是,在我的真实代码中,Base 方法得到一个错误的this 指针并不可避免地崩溃。我在调用其中一个方法之前检查了汇编代码,该方法在实际代码和示例代码中都没有参数,发现它有所不同:

工作(示例)代码

call   <std::unique_ptr<Base, std::default_delete<Base> >::operator->() const>
mov    (%eax),%edx
add    $0x8,%edx
mov    (%edx),%edx
mov    %eax,%ecx
call   *%edx

以上转换为base-&gt;method() 调用,其中basestd::unique_ptr&lt;Base&gt;。 对于那些不知道的人,类方法的调用约定可以是__thiscall,在这种情况下就是这样。这意味着this 不会在堆栈上传递,而是存储在ecx 中。上面的代码简单地将this存入ecx,然后定位method(),将其地址存入edx,并调用它。一切正常。

错误(真实)代码

call   <std::unique_ptr<Base, std::default_delete<Base> >::operator->() const>
mov    (%eax),%edx
add    $0x18,%edx
mov    (%edx),%ebx
lea    -0x24(%ebp),%edx
mov    %eax,(%esp)
movl   $0x9,-0x9c(%ebp)
mov    %edx,%ecx
call   *%ebx

这是完全相同的base-&gt;method() 调用。这次将method()的地址存入ebx。但是,this 是从堆栈外的任意位置加载的!?正如预期的那样,该程序崩溃了。任何人都知道为什么编译器会生成这样的程序集?我还在想办法。

代码

示例代码如下。实际代码在类似于示例从invoker-&gt;invoke() 调用base-&gt;check() 时崩溃。

已删除代码以节省空间。要查看它,请检查编辑历史记录。

【问题讨论】:

  • this 指针不必在不同的派生类中保持相同。如果需要最外层对象的基地址,可以使用dynamic_cast&lt;const void *&gt;iirc。
  • @AlanStokes 是的,你完全正确。我发布的代码不会重现我在真实代码中遇到的错误。实际代码中this 指针的地址超出了程序虚拟内存的范围,例如。 0x429bce80x7a55ec。我会试着弄清楚发生了什么。
  • 我已经更新了问题。
  • @n.m.它不是重复的。

标签: c++ mingw multiple-inheritance virtual-inheritance


【解决方案1】:

这是一个错误。 (551735536755453)该错误特定于gcc-i686-mingw 版本4.7.04.7.2

来自55173

当对同时使用虚拟和非虚拟继承的对象调用虚拟调用时,虚拟 thunk 会为目标函数留下无效的“this”指针。

这基本上就是我在问题中描述的内容。应该保存this的寄存器被用于非相关操作。

唯一的解决办法是降级到4.7.0以下或升级到4.7.3或以上。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-27
    • 2016-05-20
    • 1970-01-01
    • 2011-03-20
    • 1970-01-01
    • 1970-01-01
    • 2016-10-26
    • 2011-01-04
    相关资源
    最近更新 更多