In Perl, you have a nice built in library called Carp which gives you stack traces including the parameters on the stack. If you desire, you can dump the entire contents of any variable in any argument in your backtrace. If you really desire, you can modify your caller's variables.
This isn't possible in ruby-1.8.x due to mistakes or oversights in the design.
In perl, here's a sample of what you can do easily:
use Carp qw( cluck ); sub a { cluck('Message') } sub b { a( 1 .. 2 ) } sub c { b( 'a' .. 'c' ) } c();
Message at - line 2 main::a(1, 2) called at - line 3 main::b('a', 'b', 'c') called at - line 4 main::c() called at - line 5
sub b { package DB; () = caller 1; say "caller's args=@DB::args"; $DB::args[0] = 'Zappo'; return; } sub a { say "args=@_"; b(); say "args=@_"; } a( 'flash' );
# args=flash # caller's args=flash # args=Zappo
def c(x); end def b(x); c(3); end def a(x); b(2); end a(1)
rb_call(a,[1]) { rb_call(b,[2]) { rb_call(c,[3]) { } } }
http://weblog.jamisbuck.org/2006/9/22/inspecting-a-live-ruby-process
Be sure to follow the comments, too.
Re:Some help maybe
jjore on 2009-07-20T02:26:56
Ah, gleaning the information from backtrace() is nicer than using rb_eval() which would be my normal first pass trick. That is, in any language like Perl, Ruby, or I assume Python, if there's a C API that exposes an eval() function, you can get enormous powers just by driving eval() from gdb.
FWIW and because I the weblog.jamisbuck.org blog software comments aren't working for me, the clean bit of fu to glark the call stack is packaged as a GDB function thusly:
define ruby_backtrace
set $ary = (struct RArray)backtrace(-1)
set $count = (long)($ary->len)
set $index = (long)0
while $index < $count
set $str = (struct RString)rb_ary_entry($ary, $index)
set $ptr = (char*)($str->ptr)
x/1s *$ptr
set $index = (long)($index + 1)
end
endHOWEVER.
This still misses the point since what I originally complained of, the arguments to the functions are *still* missing and for exactly the same reasons.