改进GDB宏

时间:2010-05-21 09:30:54

标签: mono gdb

我有这个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

2 个答案:

答案 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