1

我的应用程序中有一个核心转储,当我尝试分析时,它似乎有损坏堆栈。谁能帮助我如何找到问题的根源。

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
4

1 回答 1

4

此堆栈可能已损坏,也可能未损坏,这也可能发生在-fomit-frame-pointer.

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

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

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

  3. 当我的堆栈变小时(就像这里的情况),我发现查看哪些候选函数调用了最后一个看起来有效的函数会很有用。

  4. 我尝试重现该问题。如果我能让事情在现场失败,那么一切都会变得容易几个数量级。

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

  6. 我通过函数候选的程序集来获得关于哪些数据结构存在于哪些偏移量的提示。

  7. 最后,有可能某些东西随机撞到了一块内存(例如,另一个线程从它自己的堆栈中溢出,错过了可能的保护页并撞到了你的堆栈。)如果你还没有任何线索,是时候扫描内存了获取指向堆栈损坏部分的指针,然后对您找到的数据结构进行逆向工程。

于 2012-10-23T15:06:01.550 回答