Devel::CallTrace - See what your code's doing


Devel-CallTrace documentation Contained in the Devel-CallTrace distribution.

Index


Code Index:

NAME

Top

Devel::CallTrace - See what your code's doing

SYNOPSIS

Top

#!/usr/bin/perl -d:CallTrace

package foo;

sub bar { print "bar\n"; baz(); }

sub baz { print "boo\n"; }

foo::bar();

RATIONALE

Top

There are a number of perl modules in the CPAN that are designed to trace a program's execution as it runs. Each uses a different trick to do its job, but none of them quite met my needs. The technique this module uses is quite simple and seems to be quite robust.

DB::sub

perl will automatically call DB::sub on each subroutine call and leave it up to us to dispatch to where we want to go.

Devel::CallTrace::called

This routine is called with two parameters:

DEPTH

The integer "depth" that this call is being called at.

PARAMS

A reference to the routine's @INC

To get at the subroutine that was being called, have a look at $DB::sub

BUGS

Top

It uses the debugger. How could it not have bugs?

SEE ALSO

Top

perldebguts, DB, a licensed therapist.

trace - Uses source filters. Scares me.

Devel::TraceCalls - Very robust API. The code seems to do all sorts of scary magic

Debug::Trace - Uses symbol table magic to wrap your functions.

Devel::TRaceFuncs - Requires developers to instrument their source files.

COPYRIGHT

Top


Devel-CallTrace documentation Contained in the Devel-CallTrace distribution.
package Devel::CallTrace;
use warnings;
use strict;
no strict 'refs';

use vars qw($SUBS_MATCHING);
our $VERSION = '1.2';

$SUBS_MATCHING = qw/.*/;

# From perldoc perlvar
# Debugger flags, so you can see what we turn on below.
#
# 0x01  Debug subroutine enter/exit.
# 
# 0x02  Line-by-line debugging.
# 
# 0x04  Switch off optimizations.
# 
# 0x08  Preserve more data for future interactive inspections.
# 
# 0x10  Keep info about source lines on which a subroutine is defined.
# 
# 0x20  Start with single-step on.
# 
# 0x40  Use subroutine address instead of name when reporting.
# 
# 0x80  Report "goto &subroutine" as well.
# 
# 0x100 Provide informative "file" names for evals based on the place they were com-
#         piled.
# 
# 0x200 Provide informative names to anonymous subroutines based on the place they
#         were compiled.
# 
# 0x400 Debug assertion subroutines enter/exit.
# 
  


BEGIN { $^P |= (0x01 | 0x80 | 0x100 | 0x200); };

sub import {


}
package DB;

# Any debugger needs to have a sub DB. It doesn't need to do anything.
sub DB{};

# We want to track how deep our subroutines go
our $CALL_DEPTH = 0;



sub sub {
    # localize CALL_DEPTH so that we don't need to decrement it after the sub 
    # is called
    local $DB::CALL_DEPTH = $DB::CALL_DEPTH+1;

    # Report on what's going on, but only if it matches our regex
    Devel::CallTrace::called($DB::CALL_DEPTH, \@_) 
        if ($DB::sub =~ $Devel::CallTrace::SUBS_MATCHING);

    # Call our subroutine. @_ gets passed on for us.
    # by calling it last, we don't need to worry about "wantarray", etc
    # by returning it like this, the caller's expectations are conveyed to 
    # the called routine
    &{$DB::sub};
}

sub Devel::CallTrace::called {
    my $depth = shift;
    my $routine = shift;
    # print STDERR is safe. warn is not. calling any routine 
    # not defined from within the DB:: package will not work. (see perldebguts)
    print STDERR " " x $depth . $DB::sub;
    if (exists $DB::sub{$DB::sub}) {
        print STDERR " ($DB::sub{$DB::sub})";
    }
    print STDERR "\n";
}

1;