【问题标题】:Interpreting cause of segfault with GDB nexti用 GDB nexti 解释段错误的原因
【发布时间】: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


【解决方案1】:

nexti 将执行下一条指令,但如果该指令是 call,则它会一直执行直到函数返回。来自GDB manual

nexti, nexti arg, ni

执行一条机器指令,但如果是函数调用,则继续执行直到函数返回。参数是重复计数,如下所示。

当您执行callq 时,调试器会调用该函数,但随后会在该函数执行期间在某处崩溃。如果你想进入一个函数调用,那么当你点击callq 0x7ffff53a2d50时我会推荐stepi

【讨论】:

    【解决方案2】:

    只要对地址 0x7ffff53a2d50 执行 callq,就会突然出现段错误。

    这通常是由堆栈溢出引起的。

    寻找深度递归(使用where 命令)。还要在info proc map 的输出中查看您的堆栈区域(包含当前的$rsp 值)。

    【讨论】:

    • 但是堆栈溢出不会只触发push 指令上的段错误吗?调用指令实际上并没有增加堆栈大小或向上移动堆栈指针
    • 绝对不是深度递归导致的栈溢出(调用栈只有7帧),也不是栈空间耗尽导致的stackoverflow——在main中放置变量的简单实验然后计算崩溃点的堆栈大小显示堆栈小于1000字节
    • @Siler A CALL 指令 PUSHes 返回堆栈上的地址,并且确实实际上减少了堆栈指针。
    猜你喜欢
    • 2017-12-21
    • 2014-05-08
    • 2011-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多