2012-10-22 66 views
1

我在应用程序中获得了核心转储,并且当我尝试分析它时,似乎它已经损坏了堆栈。任何人都可以帮助我解决问题的根源吗?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 

回答

2

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

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

  1. 获取符号。关于代码的信息越多,您必须通过自己重新创建信息来减轻痛苦。

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

  3. 当我的堆栈增长下降(这里是这种情况),我发现可以看到哪些候选函数被称为最后一个有效函数。

  4. 我尝试重现该问题。如果我能让事情失败,所有事情都会轻松一些。

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

  6. 我通过程序集为候选函数获取有关哪些数据结构出现在哪些偏移量的提示。

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