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
精彩评论