Showing posts with label gdb. Show all posts
Showing posts with label gdb. Show all posts

Thursday, April 19, 2012

Compiling perl for debugging with gdb

If you ever looked inside of perl source then you know code uses tons of C preprocessor macroses. GDB has a nice feature to expand them for you. However, you have to compile program to contain information about macroses and it took me a while to figure it out how to do it.

Short answer

    ./Configure -des -Dprefix=/Users/ruz/perl/blead -Dusedevel \
        -Doptimize='-O3 -g3' -DEBUGGING \
        -Dusemymalloc -Dusethreads -Dinc_version_list=none

Explanation

I find INSTALL very misleading, so filed a bug report and may be it will be explained in docs or Configure script will be improved.

Anyway, here is explanation. -DEBUGGING=-g3 doesn't work, it always puts -g flag. It's not clear from the doc that -Doptimize is different thing and you can put -g3 there. There is more to this, but to be short if -DDEBUGGING is set and -g* is in -Doptimize then things are not adjusted and you get what you want. However, setting -Doptimize overrides default optimization flags and you have to repeat them.

See also

Dumping perl data structures in GDB

Tuesday, July 28, 2009

Debugging perl programs/internals in gdb

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.