我有一个传统GDB命令脚本,用于根据Python 2.6源代码附带的GDB脚本获取Python堆栈跟踪(SO不允许超链接,但这里是网址:http://#%20http://svn.python.org/view/*checkout*/python/branches/release26-maint/Misc/
)传统GDB脚本中堆栈跟踪的停止条件
该脚本有一个while循环,基于退出的程序计数器有一个相当脆弱的检查,这可能仅适用于直接运行Python的情况(如注释中的原始代码所述)如果解释器是从C/C++应用程序启动的话,则不行。
现有while循环是这样的:
while $pc < Py_Main || $pc > Py_GetArgcArgv
# ...
# code for extracting Python stack from local vars in relevant frames
# of C stack
# ...
up-silently 1
因为我要调试的程序,对Py_Main
和Py_GetArgcArgv
支票都不会很好地工作,所以我在寻找一个循环条件当它达到main
时,它将评估为false。
所以我一直在玩弄使用程序计数器,帧指针和堆栈指针的想法,因为如果up-silently
失败,它们将具有与先前相同的值,这意味着我在堆栈顶部,像这样:
set $oldpc = -1
set $oldfp = -1
set $oldsp = -1
while !($oldpc == $pc && $oldfp == $fp && $oldsp == $sp)
# ...
# code for extracting Python stack from local vars in relevant frames
# of C stack
# ...
set $oldpc = $pc
set $oldsp = $sp
set $oldfp = $fp
up-silently 1
我认为这应该做的伎俩,初步检查表明它工作正常。不过,我并不太熟悉编译器可以做的各种优化,我担心可能存在某些角落的情况,他们可能有效地在堆栈中的某处处于相同位置。
看起来$fp
对于帧指针已被优化掉的呼叫可以为零(例如,通过使用GCC编译使用-g -O3
)。我也不确定$pc
是否可以依赖于不同,特别是如果递归调用正在发生。我希望$sp
会有所不同,虽然仍然有待处理的堆栈,但是我有一个模糊的怀疑,即与tail recursion相关的优化可能导致$ sp相同。
任何意见将不胜感激。
具体的问题:
问题1:是否有遗留(非Python)的GDB脚本更好的方式来弄清楚,如果你在堆栈的顶部?
问题2:将我的$sp
,$pc
和$fp
假设持有多数或全部优化方案真的吗?