Segfault:objdump和gdb之间的反汇编是不同的

时间:2014-07-18 17:22:34

标签: c++ assembly gdb objdump

[深呼吸。] 我们有一个使用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进行反汇编。)

1 个答案:

答案 0 :(得分:2)

根据@ 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__设置编译代码。