段错误:objdump和gdb的反汇编结果不同

10

[深呼吸。] 我们有一个应用程序,使用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
可能是动态链接问题吗? - BlackBear
3
在某处,你有两个使用不同编译器设置或宏定义的翻译单元或模块。因此,这两个模块在类的二进制布局上存在差异。例如 class MyWidget { MyInt a; MyInt b; }; 如果 MyInt 有时被定义为32位整数类型,有时被定义为64位整数类型,则 MyWidget::b 的偏移量将不同。 - Igor Tandetnik
你能否提供更多关于这个指令的上下文信息吗?这些指令是否正确或者也是损坏的? - Matteo Italia
4
在 https://github.com/tagged/wx/blob/master/include/wx/frame.h 中,有一些宏根据条件添加或删除类成员。这很令人担忧。请非常小心地确保在应用程序中定义这些宏的方式与库构建时定义的方式相同。 - Igor Tandetnik
我将东西发布到了 https://github.com/hendrixjl/wxmotif_problem。 - John
显示剩余5条评论
1个回答

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


我认为答案就在这里。我本来会说两个调用都在同一个翻译单元中,但是我刚刚将wxFrame :: GetWidget的函数定义移动到./src/motif /frame.cpp文件中并重新编译,问题似乎已经解决了。我不确定像__WXDEBUG__这样的任何宏在下一个翻译单元中如何不同,因为我使用./configure; make; make install编译所有内容而没有更改它。感谢您的帮助! - John
1
编译代码时出现宏未定义的错误,而不是库文件。您的 MainApp 继承自 wxAppConsole,但是如果没有启用 WXDEBUG,它的虚函数表将缺少 OnAssert 条目,因此其布局与库文件期望的不同(因为库文件是使用 WXDEBUG 编译的)。 - Jester
打自己的脑袋,我真是太蠢了!非常感谢。你给了我一个新的工具来使用(-fdump-class-hierarch)。 - John

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接