[深呼吸。]
我们有一个使用WxMotif 2.6.3弹出窗口的应用程序(GUI库不是-也不是-我的选择)。
它可以在32位ix86系统上正常运行。我的任务是将其转换为64位应用程序。它总是段错误。
我使用的是RHEL 6,因此我使用gcc 4.4.7进行了编译。经过大量的咬牙切齿后,问题似乎显而易见:在wxFrame::DoCreate中,m_mainWidget已设置(正确);在wxFrame::GetMainWidget中,它作为空指针返回。空指针会导致崩溃。
使用gdb,设置m_mainWidget的指令为

mov    %rax,0x1e0(%rdx) # $rdx = 0x68b2f0

而获取m_mainWidget的代码是
mov    0x1f0(%rax),%rax # $rax = 0x68b2f0

在gdb中,我可以检查内存并看到0x68b4d0处的指针正确。为什么偏移量不正确?

更令人困惑的是,当我使用objdump反汇编libwx_motifd_core-2.6.so.0.3.1时,“get”程序集是
  mov    0x1e0(%rax),%rax

在objdump中,get和set都使用0x1e0作为偏移量。到底是怎么回事?

我在这里上传了一些相关信息:
GitHub

我提供了一个小程序,可以在系统上复制该问题。

进一步调查,我在wxFrame::DoCreate的反汇编中看到,进一步使用m_mainWidget使用0x1e0作为偏移量检索值(反汇编在我使用-O0的编译器上,因此代码必须返回到内存每一次)。
“只是为了好玩,”我向wxFrame添加了一个新的成员变量-m_myMainWidget-并在设置了m_mainWidget之后立即进行设置。然后,我让wxFrame::GetMainWidget()返回本地值(m_myMainWidget)。您不知道吗:当我从gdb中反汇编时,崩溃仍然发生,并且GetMainWidget包含相同的+16偏移量。 (在使用objdump进行反汇编时,不存在偏移量。)

最佳答案

基于@Igor的评论,我使用-fdump-class-hierarchy编译器选项查看了类布局。事实证明,由于include/wx/app.h中的此条件块,确实存在vtable布局不匹配:

#ifdef __WXDEBUG__
    virtual void OnAssert(const wxChar *file,
                          int line,
                          const wxChar *cond,
                          const wxChar *msg);
#endif // __WXDEBUG__

您需要确保使用相同的__WXDEBUG__设置来编译代码。

08-16 11:21