2010-03-02 2 views

답변

14

많은 유용한 cor e 및 CPAN 기반 도구를 사용하여 스택 추적을 생성합니다 (다른 답변에서 설명한 것처럼). 그러나 직접 롤업하려면 caller 내장 명령을 확인하십시오. 이것을 사용하여 스택을 걸어 내려 와서 무슨 일이 일어나는지 정확하게 볼 수 있습니다.

+4

어, 아니면'Devel :: StackTrace'를 사용하십시오. – jrockway

+5

그건 좋은, 다른 옵션입니다. 그러나 외부 모듈이 필요합니다. 외부 모듈은 매력적일 수도 있고 그렇지 않을 수도 있습니다. 그냥 downvoting 대신 대답으로 게시하지 않는 이유는 무엇입니까? –

31

Carp::confess (use Carp;)은 오류의 일부로 전체 스택 추적을 제공합니다. 당신이 실패한 무언가의 부분으로 다만 그것을 필요로하는 경우에, confess는 진짜로 모두이다.

코멘트를

, 여기에 다양한 Carp 기능의 출력입니다 :

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

이 스크립트를 실행, 당신이 얻을 :

 
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 

이 스크립트를 실행하지만, STDOUT 리디렉션 (따라서 STDERR에 인쇄됩니다 어떤 표시) , 당신은 얻는다 :

 
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

그러면 스택 추적 및 오류가 STDERR로 전송됩니다. 그것을 캡쳐해야한다면 기본 Carp :: longmess()를 직접 사용하십시오. 그리고 Carp :: cluck는 고백과 비슷하지만 이후에 사망합니다. – ysth

+2

나는 그것이 거꾸로 생각한다.'cluck'는 스택 트레이스와 함께 경고이고'confess'는 죽는다. – mob

+0

err, yes, 그게 뒤로였습니다 – ysth

31

디버깅이 필요하면 Carp::Always을 좋아합니다.

perl -MCarp::Always my_script.pl 
+1

-MCarp = verbose 할 필요가있는 것처럼 보입니다. – brianegge

9

caller을 사용하는 쉬운 방법. 이 코드는 추가 모듈을 사용하지 않습니다. 필요한 곳에 포함 시키십시오.

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"; 
} 
관련 문제