GDB核心转储具有损坏的堆栈,显示“堆栈帧无法访问地址0x12处的内存”
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GDB核心转储具有损坏的堆栈,显示“堆栈帧无法访问地址0x12处的内存”相关的知识,希望对你有一定的参考价值。
我在我的应用程序中获得了一个核心转储,当我尝试分析时,它似乎有腐败堆栈。任何人都可以帮助我如何找到问题的根源。
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
答案
这个堆栈可能会或可能不会损坏,这也可能发生在-fomit-frame-pointer
。
对于它的价值,这是我目前的战略。我并不认为这是一个最佳策略,只是目前适合我的策略:
- 获取符号。您获得的有关代码的信息越多,您自己重新创建该信息所需的痛苦就越少。
- 我手动重新构建堆栈。为此,我通常开始将堆栈中找到的指针对齐值提供给“信息符号”,看看我是否可以获得任何有用的信息。缺少符号,解码在可能由值指向的存储器位置处找到的“指令”也是有用的,如果将其作为指针,则将接近已知的代码位置。这可以产生对具有符号的位置的调用。
- 当我的堆栈增长时(就像这里的情况一样),我发现查看哪些函数候选称为最后一个有效的函数会很有用。
- 我试着重现这个问题。如果我能让事情失败,那么一切都会变得更容易。
- 然后我查看堆栈并尝试确定损坏开始的偏移量。
- 我通过程序集查找函数候选者,以获得关于哪些数据结构存在于哪些偏移量的提示。
- 最后,有可能随机命中一块内存(例如,另一个线程吹过自己的堆栈,错过了可能的防护页面并击中了你的堆栈。)如果你还没有任何线索,那么它就是扫描内存的时候了。指向堆栈损坏部分的指针,然后对您找到的数据结构进行逆向工程。
以上是关于GDB核心转储具有损坏的堆栈,显示“堆栈帧无法访问地址0x12处的内存”的主要内容,如果未能解决你的问题,请参考以下文章