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