GDB如何确定堆栈的底部?

时间:2012-04-05 15:30:58

标签: c gdb

背景:我正在使用getcontext(3) / makecontext(3) / setcontext(3)ucontext.h; SUSv2,POSIX.1-2001)系列分配我自己的机器上下文和堆栈功能。

当我使用gdb(版本6.1.1)检查堆栈,而线程处于我分配的这些上下文之一时,似乎gdb不知道堆栈的结尾(逻辑底部)在哪里。例如,这是来自x86 FreeBSD的堆栈:

#0  0x2872d79f in poll () from /lib/libc.so.7
#1  0x28646e23 in poll () from /lib/libthr.so.3
#2  0x2869b267 in fdtask (task=0x28a3dc40, v=0x0) at fd.c:58
#3  0x2869c8dc in taskstart (y=681827392, x=0) at task.c:58
#4  0x00000000 in ?? ()
#5  0x28a3dc40 in ?? ()
#6  0x00000000 in ?? ()
#7  0x00000000 in ?? ()
…
#65 0x00000000 in ?? ()
…

(是的,这是建立在Russ Cox' libtask library之上的。)

这个上下文的执行从taskstart函数开始,但似乎GDB无法弄清楚它应该停止尝试读取堆栈,即使它在该帧中遇到NULL的返回地址。

我的问题是:我能做些什么(通过以某种方式格式化堆栈,或设置寄存器,任何东西)来帮助GDB了解堆栈顶部的位置?感谢。

编辑:结论:gdb 6.1.1检测到堆栈结束的一种方法是检查存储的帧指针是否为NULL;我通过修改x86和amd64 makecontext(2)函数来修复我的用例问题,以便在初始化新上下文时将ebp或rbp重置为零。 (在这种情况下,我不关心其他架构。)这个问题随着gdb 7.1而消失;据推测,gdb 7.1能够通过其他方式检测堆栈的结束,例如debuginfo。

2 个答案:

答案 0 :(得分:2)

如果GDB使用帧指针来展开堆栈(pre-DWARF2方法),它会在到达空帧指针时停止,我相信。对于DWARF2,事情要复杂得多,因为“帧指针”由堆栈指针与当前指令的insruction指针和DWARF2帧偏移信息结合隐式确定,但实际上效果是相同的。现在还不确定FreeBSD使用的是什么。

答案 1 :(得分:0)

gdb文档说明停止列出回溯帧的一种方法是在main()的返回地址之后。

请参阅位于@cindex backtrace beyond @code{main} function第6251行的gdb / doc / gdb.textinfo中的ftp://sourceware.org/pub/gdb/snapshots/current/gdb-7.4.50.20120405.tar.bz2