2010-03-02 21 views

risposta

14

Ci sono molti utili, cor e e strumenti basati su CPAN per generare una traccia di stack (come illustrano altre risposte). Tuttavia, se vuoi eseguire il rollover, controlla il built-in caller. Puoi usarlo per scendere in cima allo stack e vedere esattamente cosa sta succedendo.

+4

Uh, o usare 'Devel :: StackTrace'. – jrockway

+5

Questa è una multa, altra opzione. Ma richiede un modulo esterno, che può o non può trovare attraente. Perché non pubblicarlo semplicemente come risposta, invece di fare downvoting? –

31

Carp::confess (da use Carp;) fornisce una traccia stack completa come parte dell'errore. Se ti serve solo come parte di qualcosa che non funziona, lo confess è tutto ciò di cui hai veramente bisogno.

Per commenti, ecco l'uscita di vari Carp funzioni:

use strict; 
use warnings; 
use Carp qw/longmess cluck confess/; 

sub foo { 
    &bar; 
} 

sub bar { 
    &baz; 
} 

sub baz { 
    shift->(); 
} 

my %tests = (
    'longmess' => sub { print longmess 'longmess' }, 
    'cluck' => sub { cluck 'using cluck' }, 
    'confess' => sub { confess 'using confess' }, 
); 

while (my ($name, $sub) = each %tests) { 
    print "$name - before eval:\n"; 
    eval { 
     foo($sub); 
    }; 
    print "$name - before if:\n"; 
    if ([email protected]) { 
     print "caught: [email protected]"; 
    } 
    print "$name - done\n\n"; 
} 

esecuzione di questo script, si ottiene:

 
longmess - before eval: 
longmess at - line 14 
     main::baz called at - line 10 
     main::bar called at - line 6 
     main::foo('CODE(0x183a4d0)') called at - line 26 
     eval {...} called at - line 25 
longmess - before if: 
longmess - done 

confess - before eval: 
confess - before if: 
caught: using confess at - line 20 
     main::__ANON__() called at - line 14 
     main::baz called at - line 10 
     main::bar called at - line 6 
     main::foo('CODE(0x183a3e0)') called at - line 26 
     eval {...} called at - line 25 
confess - done 

cluck - before eval: 
using cluck at - line 19 
     main::__ANON__() called at - line 14 
     main::baz called at - line 10 
     main::bar called at - line 6 
     main::foo('CODE(0x183a434)') called at - line 26 
     eval {...} called at - line 25 
cluck - before if: 
cluck - done 

esecuzione di questo script ma reindirizzamento STDOUT (mostrando quindi ciò che viene stampato su STDERR) , ottieni:

 
using cluck at - line 19 
     main::__ANON__() called at - line 14 
     main::baz called at - line 10 
     main::bar called at - line 6 
     main::foo('CODE(0x183a434)') called at - line 26 
     eval {...} called at - line 25 
+3

Che invia lo stack trace e l'errore a STDERR; se hai bisogno di catturarlo, usa direttamente il sottostante Carp :: longmess(). E Carp :: cluck è come confessare ma muore in seguito. – ysth

+2

Penso che sia indietro - "cluck" è un warn con una traccia stack e "confess" è un dado. – mob

+0

err, sì, che era indietro – ysth

31

Per esigenze di debug, mi piace Carp::Always.

perl -MCarp::Always my_script.pl 
+1

Mi sembra di aver bisogno di fare -MCarp = verbose – brianegge

9

Modo semplice con caller. Questo codice non utilizza alcun modulo aggiuntivo. Basta includerlo dove necessario.

my $i = 1; 
print "Stack Trace:\n"; 
while ((my @call_details = (caller($i++)))){ 
    print $call_details[1].":".$call_details[2]." in function ".$call_details[3]."\n"; 
} 
Problemi correlati