linux / amd64上的c ++ debug segfault(汇编程序)

时间:2015-11-12 23:49:11

标签: c++ assembly gdb x86-64 gas

我尝试使用核心转储来调试应用程序的崩溃, 后跟踪的部分如下所示:

#0  0x00000000000000a1 in ?? ()
#1  0x000000000065e8bf in TPageGroupBase::activate() ()

据我了解,有一些"野生"跳到 此类地址0xa1,看起来this的值不正确。 我看一下TPageGroupBase::activate的反汇编,得到:

Dump of assembler code for function _ZN14TPageGroupBase8activateEv:
   0x000000000065e890 <+0>:     push   %r12
   0x000000000065e892 <+2>:     push   %rbp
   0x000000000065e893 <+3>:     push   %rbx
   0x000000000065e894 <+4>:     mov    %rdi,%rbx
   0x000000000065e897 <+7>:     mov    0xdb7e9a(%rip),%rdi        # 0x1416738 <_ZN11IPageWalker9instance_E>
   0x000000000065e89e <+14>:    mov    (%rdi),%rax
   0x000000000065e8a1 <+17>:    callq  *0x40(%rax)
   0x000000000065e8a4 <+20>:    mov    0x48(%rbx),%rbp
   0x000000000065e8a8 <+24>:    xor    %esi,%esi
   0x000000000065e8aa <+26>:    mov    %rax,%r12
   0x000000000065e8ad <+29>:    cmp    $0x1,%r12
   0x000000000065e8b1 <+33>:    seta   %sil
   0x000000000065e8b5 <+37>:    mov    0x50(%rbp),%rdi
   0x000000000065e8b9 <+41>:    mov    (%rdi),%rax
   0x000000000065e8bc <+44>:    callq  *0x68(%rax)
=> 0x000000000065e8bf <+47>:    cmp    $0x1,%r12
   0x000000000065e8c3 <+51>:    jbe    0x65e978 <_ZN14TPageGroupBase8activateEv+232>

更新:根据Jester的说法(谢谢)我应该将之前的指令视为狂野跳跃的原因。

因此,重新启动调试符号启用,重新启动测试并再次崩溃:

769         back_btn_->setVisible(val);
   0x000000000091c14d <+29>:    mov    0x50(%rdi),%rdi
   0x000000000091c151 <+33>:    mov    (%rdi),%rax
   0x000000000091c154 <+36>:    movzbl %sil,%esi
   0x000000000091c158 <+40>:    callq  *0x68(%rax)

back_btn_是QSvgWidget(http://doc.qt.io/qt-4.8/qsvgwidget.html),QSvgWidget::setVisible是虚拟的,

了解gas手册在最后一条指令中我们有:

p/x *(unsigned *)($rax+0x68)
 $7 = 0x141

作为跳转的地址,这会导致崩溃。

我理解(感谢您的评论),我们在这里加载虚函数的地址,

p/x *(unsigned *)($rdi+0x58)
$8 = 0x0

所以看起来像对象的虚拟地址是null, 我以为我不会以某种方式初始化back_btn_, 但是:

(gdb) p back_btn_
$9 = (QSvgWidget *) 0x36fe3f0

和此地址类似于其他有效地址 对象,所以有人破坏它的内容,并将其归零 虚拟表,我是对的吗?

我可以从这个coredump中提取更多内容吗?

0 个答案:

没有答案