2013-05-29 2 views
1

coro 버전 6.06을 사용하는 Perl 코드가 있습니다.펄 코어 분할 오류

{ 
package AAA; 
use AnyEvent::HTTP::LWP::UserAgent; 
use Coro; 
use Coro::AnyEvent; BEGIN { *CORE::GLOBAL::sleep = \&Coro::AnyEvent::sleep; }; 

sub new { return bless {} => shift }; 

sub main { 
    my ($self) = @_; 

    my $count = 1000; 
    my $h = {}; 
    while (1) { 
     while (keys %$h >= $count) { 
      sleep 1; 
     } 

     my $task = rand(1000); 

     my $coro = async (
      sub { 
       my ($self, $task) = @_; 
       sleep(rand(1000)); 
       print ": $self - $coro - $task\n"; 
      } => ($self, $task) 
     ); 

     $h->{$coro} = $coro; 
     $coro->on_destroy(sub { 
      delete $h->{$coro}; 
      undef $coro; 
     }); 
    } 
    } 
} 

AAA->new->main; 

때때로 (같은 하루에 1 시간)이 분할 오류 오류와 함께 실패합니다

내 코드입니다.

어떤 버그가 있으며 어떻게 감지 할 수 있습니까?

+0

코어 버전 6.06 – Nikita

답변

0

역 추적 (예 : 코어 덤프에서 제외)이 없으면 이유를 밝히기가 어렵습니다. 충돌 한 위치에 대한 정보를 제공하지 않았기 때문입니다.

그러나 PERL의 오랜 버그로 인해 C 라이브러리 (예 : EV 또는 Coro)로 인한 충돌이 자주 발생합니다. 인터프리터가 종료되면 데이터 구조가 손상 될 수 있습니다 (일반적으로 순환 데이터 구조의 일부 또는), 즉 perl은 여전히 ​​다른 곳에서 참조 된 구조를 해제 할 수 있습니다.

AnyEvent 또는 Coro를 사용하는 코드와 같이 콜백이 많은 코드를 사용하면 순환 데이터 구조를 만드는 것이 다소 쉽습니다.

다음과 같은 시나리오가 발생할 수 있습니다. 프로그램이 종료됩니다 (예 : 런타임 오류로 인해 catch하지 않고 예외가 발생하고 프로그램이 종료되는 동안 perl이 segfault를 일으키는 일부 C 데이터 구조를 손상시킵니다) 이는 또한 실제로 오류 메시지를 보지 못한다는 것을 의미합니다.

코어 럽트의 백 트레이스에서 실제 오류가있는 Perl_croak 또는 Perl_vcroak에 대한 호출을 볼 수 있습니다.

그 perl 버그에 대한 유일한 해결책은 프로그램 종료시에 데이터 구조를 해제하는 것입니다 (예를 들어, 전역 변수를 종료하기 전에 undef'ing). 당신이 그것을 할 수 없다면 (예를 들어 하나의 실마리가 없기 때문에 :), 당신은 (당신의 코드를 eval에 래핑함으로써) 런타임 오류를 스스로 잡을 수 있고 프로그램을 정상적으로 종료하는 대신 오류를 출력하고 POSIX :: _ exit 1 예를 들면.

AnyEvent :: Debug를 사용하면 모든 감시자 콜백이 평가판으로 래핑되고 오류가보고되므로 시작할 수도 있습니다.