2013-05-29 61 views
1

我有一個使用coro版本6.06的Perl代碼。perl coro分段錯誤

這是我的代碼:

{ 
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

Coro版本是6.06 – Nikita

回答

0

沒有回溯(例如從一個coredump)很難說爲什麼,因爲你沒有提供有關它崩潰的信息。

然而,崩潰與C庫(例如EV或科羅)是因爲在Perl的長期缺陷的共同:當解釋器退出時,它有時破壞數據結構(通常是那些直接或間接地具有圓形的數據結構的一部分),也就是說,perl可以釋放仍在別處引用的結構。

對於使用AnyEvent或Coro的代碼(如代碼)來說,創建循環數據結構要容易一些。

以下情況可能導致:您的程序退出(例如,因爲它會引發異常而不捕獲它(例如,由於運行時錯誤),並且在程序退出期間,perl會破壞導致段錯誤的一些C數據結構,這也意味着你實際上並沒有看到錯誤信息。

在coredump的回溯中,您可能會看到調用Perl_croak或Perl_vcroak的實際錯誤。

該perl錯誤的唯一解決方法是在程序退出時自行釋放數據結構(例如,通過在退出前自行解除全局變量)。如果你不能這樣做(例如,因爲你不知道它是否是:),你可以自己捕獲運行時錯誤(通過將代碼包裝到eval中),而不是通常退出程序,你可以打印錯誤並調用例如,POSIX :: _ exit 1。

使用AnyEvent :: Debug會將所有觀察者回調包裝到一個評估中,併爲他們報告錯誤,所以這可能是一個開始。