Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to restrict perl debugging in a given set of modules or lib path?

Tags:

debugging

perl

When debugging a perl program with perl -d, How can I restrict it to step in only given set of modules or a path to lib ?

like image 223
vp8 Avatar asked Oct 29 '22 20:10

vp8


1 Answers

The DB::cmd_b_sub or DB::break_subroutine functions set a breakpoint at the start of an arbitrary function. You can walk the stash to find the set of arguments to pass to this function. For example,

sub add_breakpoints_for_module {
    my $module = shift;
    return unless $INC{"perl5db.pl"};    # i.e., unless debugger is on
    no strict 'refs';
    for my $sub (eval "values %" . $module . "::") {
        if (defined &$sub) {          # if the symbol is valid sub name
            DB::cmd_b_sub(substr($sub,1));   # add breakpoint
        }
    }
}

This code should be run after the relevant modules have been loaded.


And here's how to use this idea as a separate library. Save this code to Devel/ModuleBreaker.pm somewhere on your @INC path and invoke the debugger as

perl -d:ModuleBreaker=Some::Module,Some::Other::Module script_to_debug.pl args

.

# Devel/ModuleBreaker.pm - automatically break in all subs in arbitrary modules
package Devel::ModuleBreaker;
sub import {
    my ($class,@modules) = @_;
    our @POSTPONE = @modules;
    require "perl5db.pl";
}
CHECK { # expect compile-time mods have been loaded before CHECK phase
    for my $module (our @POSTPONE) {
        no strict 'refs';
        for my $sub (eval "values %" . $module . "::") {
            defined &$sub && DB::cmd_b_sub(substr($sub,1));
        }
    }
}
1;

And here's a version that will break on subroutines that match arbitrary patterns (which should make it easier to break inside submodules). It takes advantage of the %DB::sub table, which has information about all loaded subroutines (including anonymous subs).

package Devel::SubBreaker;
# install as Devel/SubBreaker.pm on @INC
# usage:  perl -d:SubBreaker=pattern1,pattern2,... script_to_debug.pl args
sub import {
    my $class = shift;
    our @patterns = @_;
    require "perl5db.pl";
}
CHECK {
    foreach my $sub (keys %DB::sub) {
        foreach my $pattern (our @patterns) {
            $sub =~ $pattern and DB::cmd_b_sub($sub), last;
        }
    }
}
like image 174
mob Avatar answered Nov 15 '22 07:11

mob