开发者

Improve GDB macro

开发者 https://www.devze.com 2023-01-01 02:06 出处:网络
I have this gdb macro, which is used to print meaningful stacktraces when debugging the mono runtime. It iterates over all stackframes, figures out if that frame is native or managed. If it is managed

I have this gdb macro, which is used to print meaningful stacktraces when debugging the mono runtime. It iterates over all stackframes, figures out if that frame is native or managed. If it is managed, it uses info from mono_pmip() to print a decent description of that frame. If it is native, it calls gdb's "frame" to describe the frame.

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

Two questions related to this:

How can I remove the $arg0 argument, and have it loop trough all frames, until it reaches the top of the stack?

How can I get "frame" (or an alternative) to only print the name of the function (like bt does), and not the actual line of sourcecode in that function?. Current output is:

#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);

Whereas I'd like the output to match what bt does:

#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


How can I remove the $arg0 argument, and have it loop trough all frames, until it reaches the top of the stack?

Just do while (1). Eventually up-silently will fail, and the evaluation will stop.

How can I get "frame" (or an alternative) to only print the name of the function (like bt does), and not the actual line of sourcecode in that function?

In GDB 7.3 frames got exposed to Python, giving you much finer programmatic control over them.


up-silently doesn't work with thread apply all, because it actually stops all command processing on errors. So it is not possible to get backtrace for all threads this way.

I've managed to work it around by using a small amount of Python code.

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
0

精彩评论

暂无评论...
验证码 换一张
取 消