dstar has asked for the wisdom of the Perl Monks concerning the following question:

I've inherited a module, and it's rather... hairy to maintain. It would be really nice to be able to use the debugger on it, but instead of having subroutines that you call, it loads a whole bunch of stuff into a package variable when it's 'use'ed, so by the time I get the chance to do anything with the debugger, it's already run through all of its code. Is there any way to use the debugger on a module?

Replies are listed 'Best First'.
Re: Debugging a module?
by rhesa (Vicar) on Apr 06, 2006 at 01:06 UTC
    How about not useing it, but require instead? Something like this:
    #!/usr/bin/perl require Hairy::Module; # optionally, also import its symbols: # import Hairy::Module;
    That would allow you to step through the code, since it's done at runtime instead of compile time.
      I should have mentioned that I tried that, and _weird_ things happened. For example, I couldn't set a breakpoint at _any_ line; no matter what line I tried, I got 'line xxx not breakable'. I'm assuming that there's some trick needed that I don't know about.
        In the debugger, you first have to point to the module file with f Module.pm, then you can set breakpoints. (f also takes regexen, so you don't have to be too particular unless there's an ambiguity.)

        On the other hand, you should be able to step into the require, though I've not tried it myself. (I have stepped into an eval, which would seem to be more difficult for a debugger to manage.)

        -QM
        --
        Quantum Mechanics: The dreams stuff is made of

        Good question, and I don't know. Since you're the maintainer, I'd forget about the debugger for a bit, and try adding some warn Dumper($some_var) in places.

        Without seeing the code, this is a long shot, but maybe you'd be helped by wrapping the nasty code in a sub of your own. That might kickstart the debugger.

Re: Debugging a module?
by Popcorn Dave (Abbot) on Apr 06, 2006 at 02:27 UTC
    You might have a look at ptkdb - The Perk Graphical Debugger becuase I know when I've been debugging code using this, and I forget to step over a module function call, it goes in to the module and keeps tracing. Might just be what you're after.

    Useless trivia: In the 2004 Las Vegas phone book there are approximately 28 pages of ads for massage, but almost 200 for lawyers.
Re: Debugging a module?
by sfink (Deacon) on Apr 06, 2006 at 06:03 UTC
    Put $DB::single = 1; just before the first line you want to stop at in the module. I rarely use breakpoints with the perl debugger anymore, since that trick works just as well in BEGIN blocks as in regular code, and it works well as a conditional breakpoint too:

    $DB::single = 1 if $name eq 'mark';

    which I prefer for no apparent reason to

    $DB::single = ($name eq 'mark');

    Alternatively, you could put BEGIN { $DB::single = 1; } just before you use the module, but there's a good chance you'll end up stepping through a bunch of other modules you don't care about that way.

      If I do the $DB::single = 1 with a use statement, it breaks on the last line of the module -- which is '1;'. With a require statement, I get the results I mentioned easily. I haven't tried wrapping it in a BEGIN statement -- that's a good idea.
        Either your perl behaves very differently from mine, or I didn't describe it very well. If I use these two files:

        driver.pl

        use TestModule; print "I am exiting now.\n";

        TestModule.pm

        package TestModule; our $x = 0; $DB::single = 1; our $y = $x + 1; our $z = $y ** 3; sub blah { "blah!" } 1;

        ...and run perl -d driver.pl, the debugger immediately stops at the line our $y = $x + 1. Do you get different results?

Re: Debugging a module?
by GrandFather (Saint) on Apr 06, 2006 at 01:02 UTC

    Not so much a "this is how you do it", but a "that ought be possible" answer:

    In a Windows context I use the Komodo IDE which uses the Perl debugger under the hood. I have no trouble setting break points in modules so I presume with the right incantation in the debugger you can set breakpoints in modules that are loaded by the code you are running.


    DWIM is Perl's answer to Gödel