![](/img/trans.png)
[英]What does ?? in gdb backtrace mean and how to get the actual stack frames?
[英]How does GDB determine the bottom of the stack?
背景:我正在使用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 库之上的。)
此上下文的执行从taskstart
function 开始,但似乎 GDB 无法确定它应该停止尝试读取堆栈,即使它在该帧中命中了返回地址 NULL。
我的问题是:有什么我可以做的(通过以某种方式格式化堆栈,或设置寄存器等)来帮助 GDB 了解堆栈顶部在哪里? 谢谢。
编辑:结论:似乎 gdb 6.1.1 检测堆栈末尾的一种方法是检查存储的帧指针是否为 NULL; 我通过修改 x86 和 amd64 makecontext(2)
function 以在初始化新上下文时将 ebp 或 rbp 重置为零来解决我的用例的问题。 (在这种情况下,我不关心其他架构。)这个问题随着 gdb 7.1 消失了; 大概 gdb 7.1 能够通过一些其他方式检测堆栈结束,例如 debuginfo。
我相信,如果 GDB 使用帧指针展开堆栈(DWARF2 之前的方法),它会在到达 null 帧指针时停止。 对于 DWARF2,事情要复杂得多,因为“帧指针”是由堆栈指针结合当前指令的指令指针和 DWARF2 帧偏移信息隐式确定的,但本质上效果是相同的。 不确定这些天使用哪个 FreeBSD。
gdb
文档说它停止列出回溯帧的一种方法是在main()
的返回地址之后。
请参阅 gdb/doc/gdb.textinfo 中的ftp://sourceware.org/pub/gdb/snapshots/current/gdb-7.4.50.20120405.tar.bz2 @cindex @cindex backtrace beyond @code{main} function
line 6251。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.