When it comes to perl internals, print based debugging doesn't work that well. Compilation and installation are too slow and you can not place a print and quickly see output. At some point gbd should be used. In perl world we have Devel::Peek's Dump function to look behind curtain. In C world there is sv_dump.
# threaded perl: (gdb) call Perl_sv_dump(my_perl, variable) # not threaded perl: (gdb) call Perl_sv_dump(variable)
Perl_ prefix is some magic, I don't care much why, but in most cases you need prefix things.
Using breakpoints is a must. Use pp_* functions to break, for example Perl_pp_entersub. Here is simple session where we stop before entering a sub and using dumper to figure out sub's name:
> gdb ./perl GNU gdb 6.3.50-20050815 (Apple version gdb-962) (Sat Jul 26 08:14:40 UTC 2008) (gdb) break Perl_pp_entersub Breakpoint 1 at 0xe512c: file pp_hot.c, line 2663. (gdb) run -e 'sub foo { return $x } foo()' Breakpoint 1, Perl_pp_entersub (my_perl=0x800000) at pp_hot.c:2663 2663 dVAR; dSP; dPOPss; (gdb) n 2662 { (gdb) 2663 dVAR; dSP; dPOPss; (gdb) 2668 const bool hasargs = (PL_op->op_flags & OPf_STACKED) != 0; (gdb) 2670 if (!sv) (gdb) call Perl_sv_dump(my_perl, sv) SV = PVGV(0x8103fc) at 0x813ef0 REFCNT = 2 FLAGS = (MULTI,IN_PAD) NAME = "foo" NAMELEN = 3 GvSTASH = 0x8038f0 "main" GP = 0x3078f0 SV = 0x0 REFCNT = 1 IO = 0x0 FORM = 0x0 AV = 0x0 HV = 0x0 CV = 0x813eb0 CVGEN = 0x0 LINE = 1 FILE = "-e" FLAGS = 0xa EGV = 0x813ef0 "foo"
Quite simple, but when you start investigating internals it's very helpful.
No comments:
Post a Comment