我尝试使用核心转储来调试应用程序的崩溃, 后跟踪的部分如下所示:
#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中提取更多内容吗?