2010-03-02 12 views

Respuesta

14

Hay muchos útiles, cor e y herramientas basadas en CPAN para generar un seguimiento de pila (como lo ilustran otras respuestas). Sin embargo, si desea imprimir el suyo, consulte el caller incorporado. Puede usar esto para bajar la pila y ver exactamente qué está sucediendo.

+4

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

+5

Esa es una buena opción, otra. Pero requiere un módulo externo, que puede ser atractivo o no. ¿Por qué no simplemente publicar eso como una respuesta, en lugar de bajar el voto? –

31

Carp::confess (de use Carp;) le dará un seguimiento completo de la pila como parte del error. Si solo lo necesita como parte de algo que falla, confess es todo lo que realmente necesita.

por los comentarios, aquí está la salida de varios Carp funciones:

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"; 
} 

ejecutar este script, se obtiene:

 
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 

La ejecución de este guión, pero redirigiendo la salida estándar (mostrando así lo que se imprime en stderr) , obtienes:

 
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

Eso envía la traza de la pila y el error a STDERR; si necesita capturarlo, use directamente el Carp :: longmess subyacente(). Y Carp :: cluck es como confesar pero muere después. – ysth

+2

Creo que está al revés: 'cluck' es una advertencia con un seguimiento de pila y' confess' es un dado. – mob

+0

err, sí, eso estaba al revés – ysth

31

Para las necesidades de depuración, me gusta Carp::Always.

perl -MCarp::Always my_script.pl 
+1

Parece que necesito hacer -MCarp = verbose – brianegge

9

Manera fácil usando caller. Este código no usa ningún módulo adicional. Solo inclúyelo donde sea necesario.

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"; 
} 
Cuestiones relacionadas