【发布时间】:2015-08-28 18:40:33
【问题描述】:
所以,我正在调试一个通过 SIGSEGV 神秘崩溃的程序。该程序是单线程的。
我之前调试过许多段错误 - 其中大部分归结为堆栈或堆损坏。使用 valgrind 调试堆损坏问题通常很容易。堆栈损坏比较棘手,但是当 GDB 显示您的堆栈已损坏时,您通常至少可以判断堆栈损坏是问题所在。
但是,在这里我遇到了一个我从未见过的非常奇怪的问题。使用 GDB 逐条执行指令,我看到在 callq 指令之后立即发生段错误。除了callq 地址不是从寄存器或内存中动态加载的——它只是一个静态 函数地址:
(gdb) ni
0x00007ffff659c423 223 setPolicyDocumentLoader(docLoader);
1: x/i $pc
=> 0x7ffff659c423 <WebCore::FrameLoader::init()+351>: mov %rdx,%rsi
(gdb)
0x00007ffff659c426 223 setPolicyDocumentLoader(docLoader);
1: x/i $pc
=> 0x7ffff659c426 <WebCore::FrameLoader::init()+354>: mov %rax,%rdi
(gdb)
0x00007ffff659c429 223 setPolicyDocumentLoader(docLoader);
1: x/i $pc
=> 0x7ffff659c429 <WebCore::FrameLoader::init()+357>:
callq 0x7ffff53a2d50 <_ZN7WebCore11FrameLoader23setPolicyDocumentLoaderEPNS_14DocumentLoaderE@plt>
(gdb) ni
Program received signal SIGSEGV, Segmentation fault.
0x0000000000683670 in ?? ()
1: x/i $pc
=> 0x683670: add %al,(%rax)
(gdb)
所以,一旦它执行callq 到地址0x7ffff53a2d50,它就会突然出现段错误。
我意识到,一般而言,Stackoverflow 对大多数段错误或此类问题可能没有太大帮助,因为原因往往非常特定于某些特定情况,通常归结为程序员错误导致的内存损坏.
但我仍然认为值得提出这个问题,因为这对我来说根本没有任何意义。当程序执行callq 指令到合法的静态 确定的函数地址时,操作系统如何可能 传递 SIGSEGV?
【问题讨论】:
-
ni跨过call。故障在别处,更深。您应该改用si来单步执行被调用的函数。
标签: c++ assembly segmentation-fault gdb x86-64