我有这个gdb宏,用于在调试单声道运行时打印有意义的堆栈跟踪。它迭代所有堆栈帧,确定该帧是本机还是托管。如果它是托管的,它使用来自mono_pmip()的信息来打印该帧的正确描述。如果是原生的,它会调用gdb的“框架”来描述框架。
define mono_backtrace
select-frame 0
set $i = 0
while ($i < $arg0)
set $foo = mono_pmip ($pc)
if ($foo == 0x00)
frame
else
printf "#%d %p in %s\n", $i, $pc, $foo
end
up-silently
set $i = $i + 1
end
end
与此相关的两个问题:
如何删除$ arg0参数,让它循环遍历所有帧,直到它到达堆栈的顶部?
如何才能获得“框架”(或替代)仅打印函数的名称(如bt),而不是该函数中的实际源代码行?目前的输出是:
#1 0x000c21f6 in mono_handle_exception (ctx=0xbfffe7f0, obj=0x64bf18, original_ip=0x65024a, test_only=0) at mini-exceptions.c:1504
1504 return mono_handle_exception_internal (ctx, obj, original_ip, test_only, NULL, NULL);
#2 0x00115b92 in mono_x86_throw_exception (regs=0xbfffe850, exc=0x64bf18, eip=6619722, rethrow=0) at exceptions-x86.c:438
438 mono_handle_exception (&ctx, exc, (gpointer)eip, FALSE);
而我希望输出与bt的作用匹配:
#1 0x000c21f6 in mono_handle_exception (ctx=0xbfffe7f0, obj=0x64bf18, original_ip=0x65024a, test_only=0) at mini-exceptions.c:1504
#2 0x00115b92 in mono_x86_throw_exception (regs=0xbfffe850, exc=0x64bf18, eip=6619722, rethrow=0) at exceptions-x86.c:438
答案 0 :(得分:0)
如何删除$ arg0参数,让它循环遍历所有帧,直到它到达堆栈的顶部?
做while (1)
。最终up-silently
将失败,评估将停止。
如何才能获得“框架”(或替代方案)以仅打印函数的名称(如bt),而不是该函数中的实际源代码行?
在GDB 7.3 frames got exposed to Python中,为您提供更精细的程序控制。
答案 1 :(得分:0)
up-silently
不能与thread apply all
一起使用,因为它实际上会停止对错误的所有命令处理。因此,不可能以这种方式为所有线程进行回溯。
我已经设法通过使用少量Python代码来解决这个问题。
python
class Frame_Valid (gdb.Function):
def __init__ (self):
super (Frame_Valid, self).__init__ ("frame_valid")
def invoke (self):
return gdb.selected_frame().is_valid()
Frame_Valid ()
end
define mono_backtrace
set $i = 0
select-frame $i
while ($frame_valid())
set $foo = (char*) mono_pmip ($pc)
if ($foo)
printf "#%d %p in %s\n", $i, $pc, $foo
else
frame
end
set $i = $i + 1
select-frame $i
end
end