Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Perl debug. How do I find calling line number?

by brycen (Monk)
on Sep 26, 2004 at 09:59 UTC ( #393912=perlquestion: print w/ replies, xml ) Need Help??
brycen has asked for the wisdom of the Perl Monks concerning the following question:

Let's say I have a subroutine that "dies". How can I determine what line called the subroutine? Debugger "Stack Trace" seems the obvious answer, but it does not work for me:
 print "Hello\n";
 a(0);
 print "Middle\n";
 a(1);
 print "Goodbye\n";

 sub a {
    $parameter = shift;
    if( $parameter ) { die };
 }

bash> perl -d test.pl 
Default die handler restored.
Loading DB routines from perl5db.pl version 1.07
Editor support available.

DB<1> c
  Hello
  Middle
  Died at test.pl line 10.
  Debugged program terminated.
  
DB<1> T
  $ = DB::fake::at_exit() called from file
  /usr/local/lib/perl5/5.6.1/perl5db.pl' line 2697
  $ = DB::END() called from file `test.pl' line 0
  $ = eval {...} called from file `test.pl' line 0

DB<1> 
While it died at line 10, what line called the subroutine that died?

Comment on Perl debug. How do I find calling line number?
Re: Perl debug. How do I find calling line number?
by Corion (Pope) on Sep 26, 2004 at 10:04 UTC

    It sounds to me like Carp and its replacement for die, croak is what you really want here. croak dies "at the place of call" instead of within your module. The source code of Carp.pm should also tell you how to get the information about the line number out of perl. perldoc -f caller also tells you how to get this information yourself.

      I particularly like the confess function of carp. It is just such a good name for what it does *. It captures both the angst and the deeply spiritual nature of debugging in a single word. Confess damnit :-)

      * dies with complete call stack trace

      cheers

      tachyon

      Try this: http://www.perlmonks.org/?node=caller
Re: Perl debug. How do I find calling line number?
by strat (Canon) on Sep 26, 2004 at 10:45 UTC

    For development- or debugging-purpose I like to use something like the following piece of code:

    # somewhere at the beginning of the code $SIG{__WARN__} = \&Warning; $SIG{__DIE__} = \&Die; # anywhere # ------------------------------------------------------------ sub Warning { my @text = @_; warn "------------------------------------------------------------ +\n"; warn "WARNING: @text\n"; my $count = 0; { my ($package, $filename, $line, $sub) = caller($count); last unless defined $line; warn sprintf("%02i %5i %-35s %-20s\n", $count++, $line, $sub, $filename); redo; } } # Warning # ------------------------------------------------------------ sub Die { my @text = @_; warn "------------------------------------------------------------ +\n"; warn "FATAL ERROR: @text\n"; my $count = 0; { my ($package, $filename, $line, $sub) = caller($count); last unless defined $line; warn sprintf("%02i %5i %-35s %-20s\n", $count++, $line, $sub, $filename); redo; } exit 1; } # Die # ------------------------------------------------------------

    This installs "signal handlers" for die and warn which are executed every time when the functions die and warn are executed and print a backtrace on how the line the warning or die was produced was reached...

    Best regards,
    perl -e "s>>*F>e=>y)\*martinF)stronat)=>print,print v8.8.8.32.11.32"

Re: Perl debug. How do I find calling line number?
by ambrus (Abbot) on Sep 26, 2004 at 11:49 UTC

    The problem is that when you ask for the traceback, the program has already died, so the call stack is destroyed.

    To solve the problem, you have to arrange to stop the program before it dies.

    In this case for example, first put the die in a separate line:

    255[am]king ~/a$ cat a print "Hello\n"; a(0); print "Middle\n"; a(1); print "Goodbye\n"; sub a { $parameter = shift; if( $parameter ) { die # <--- line 10 }; }
    Then run the code and see it dies at line 10
    [am]king ~/a$ perl a Hello Middle Died at a line 10.
    Than put a breakpoint to line 10
    255[am]king ~/a$ perl -wd a Loading DB routines from perl5db.pl version 1.27 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(a:1): print "Hello\n"; DB<1> b 10 DB<2> c Hello Middle main::a(a:10): die # <--- line 10 DB<2> T . = main::a(1) called from file `a' line 4 DB<2> Died at a line 10. at a line 10 main::a(1) called at a line 4 255[am]king ~/a$
    And you'll see that the subroutine was called from line 4.
Re: Perl debug. How do I find calling line number?
by itub (Priest) on Sep 26, 2004 at 14:44 UTC
    use diagnostics;
    perl -Mdiagnostics test.pl
    Hello
    Middle
    Died at test.pl line 9 (#1)
        (F) You passed die() an empty string (the equivalent of die "") or
        you called it with no args and both $@ and $_ were empty.
         
    Uncaught exception from user code:
            Died at - line 9.
            main::a(1) called at - line 4
    
Re: Perl debug. How do I find calling line number?
by pg (Canon) on Sep 26, 2004 at 15:19 UTC

    Obviously it would be nicer if you can trace the call stack, or the chain of exceptions. However, in this case, you yourself actually made the situation difficult. Why not die with some meaningful message? In pratical you should always call die with a meaningful hint:

    print "Hello\n"; a(0); print "Middle\n"; a(1); print "Goodbye\n"; sub a { $parameter = shift; if( $parameter ) { die "parameter = $parameter\n"}; }

    Lots of time, there are simple answers to difficult situations.

      It is not always possible to arrange for a graceful death.

      The script that inspired my question dynamically generated arguments, and the failure was based on complex conditions. I really DID need to know what line it came from. Printing out the bad argument (which I did do) was not enough.

Re: Perl debug. How do I find calling line number?
by pg (Canon) on Sep 26, 2004 at 15:29 UTC

    Actually, if you turn on t at the beginning of your debugging, perl -d does tell you who called the function. Here is the screen shot:

    C:\Perl\bin>perl -d b.pl Loading DB routines from perl5db.pl version 1.25 Editor support available. Enter h or `h h' for help, or `perldoc perldebug' for more help. main::(b.pl:1): print "Hello\n"; DB<1> t Trace = on DB<1> s Hello main::(b.pl:2): a(0); DB<1> s main::a(b.pl:8): $parameter = shift; DB<1> s main::a(b.pl:9): if( $parameter ) { die }; DB<1> s main::(b.pl:3): print "Middle\n"; DB<1> s Middle main::(b.pl:4): a(1); DB<1> s main::a(b.pl:8): $parameter = shift; DB<1> s main::a(b.pl:9): if( $parameter ) { die }; DB<1> s main::a(b.pl:9): if( $parameter ) { die }; DB<1> s Died at b.pl line 9. main::a(1) called at b.pl line 4 Debugged program terminated. Use q to quit or R to restart, use O inhibit_exit to avoid stopping after program termination, h q, h R or h O to get additional info. DB<1>
      Cool.

      The real script that inspired the example ran for two hours before dying. Under 'trace' I imagine it would run for a decade. But that's a great tip for smaller scripts.

Re: Perl debug. How do I find calling line number?
by Anonymous Monk on Sep 27, 2004 at 06:31 UTC
    The use of __LINE__ could be handy for a quick solution:
    print "Hello\n"; a(0, __LINE__); print "Middle\n"; a(1, __LINE__); print "Goodbye\n"; sub a { ($parameter, $line) = @_; if( $parameter ) { die "$line\n";}; }

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://393912]
Approved by Corion
Front-paged by tachyon
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (7)
As of 2014-07-30 23:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (241 votes), past polls