GDB核心转储具有损坏的堆栈,显示“堆栈帧无法访问地址0x12处的内存”

时间:2012-10-22 07:31:02

标签: gdb core

我的应用程序中有一个核心转储,当我尝试分析时,它似乎有腐败堆栈。任何人都可以帮助我如何找到问题的根源。

Program terminated with signal 11, Segmentation fault.
#0  0x40173f54 in nanosleep () from /lib/libc.so.6
(gdb) bt
#0  0x40173f54 in nanosleep () from /lib/libc.so.6
#1  0x401b2a1c in __libc_enable_asynccancel () from /lib/libc.so.6
#2  0x0000cdb8 in ?? ()
Cannot access memory at address 0x12



(gdb) info frame
Stack level 0, frame at 0xbeaedbc0:
 pc = 0x40173f54 in nanosleep; saved pc 0x401b2a1c
 called by frame at 0xbeaedbd8
 Arglist at 0xbeaedbc0, args:
 Locals at 0xbeaedbc0, Previous frame's sp is 0xbeaedbc0
(gdb) info frame 1
Stack frame at 0xbeaedbd8:
 pc = 0x401b2a1c in __libc_enable_asynccancel; saved pc 0xcdb8
 called by frame at Cannot access memory at address 0x12
(gdb) info frame 2
Stack frame at Cannot access memory at address 0x12

1 个答案:

答案 0 :(得分:3)

此堆栈可能会或可能不会损坏,这也可能发生在-fomit-frame-pointer

对于它的价值,这是我目前的战略。我并不认为这是一个最佳策略,只是目前适用于我的策略:

  1. 获取符号。您获得的有关代码的信息越多,您自己重新创建该信息所需的痛苦就越少。

  2. 我手动重新构建堆栈。为此,我通常开始将堆栈中找到的指针对齐值提供给“信息符号”,看看我是否可以获得任何有用的信息。缺少符号,解码在可能由值指向的存储器位置处找到的“指令”也是有用的,如果将其作为指针,则将接近已知的代码位置。这可以产生对具有符号的位置的调用。

  3. 当我的堆栈增长时(就像这里的情况一样),我发现查看哪些候选函数称为最后一个有效的函数会很有用。

  4. 我尝试重现问题。如果我能让事情失败,那么一切都要容易了。

  5. 然后我查看堆栈并尝试确定损坏开始的偏移量。

  6. 我通过程序集查找函数候选者,以获取有关哪些数据结构存在哪些偏移量的提示。

  7. 最后有可能随机命中一块内存(例如,另一个线程吹过自己的堆栈,错过了可能的防护页面并击中你的堆栈。)如果你还没有任何线索,是时候扫描内存指向堆栈损坏部分的指针,然后对你找到的数据结构进行逆向工程。