perl coro分段故障

时间:2013-05-29 13:16:11

标签: perl segmentation-fault

我使用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 :(得分:0)

没有回溯(例如来自coredump),很难说出原因,因为你没有提供崩溃地点的信息。

然而,由于perl中长期存在的错误,C库(例如EV或Coro)的崩溃很常见:当解释器退出时,它有时会破坏数据结构(通常是直接或间接是循环数据结构的一部分)也就是说,perl可能会释放仍在其他地方引用的结构。

使用AnyEvent或Coro的代码(如使用AnyEvent或Coro的代码)可以更轻松地创建循环数据结构。

以下场景可能会导致:您的程序退出(例如,因为它抛出异常而不捕获它,例如由于运行时错误)并且在程序退出期间,perl会破坏导致段错误的某些C数据结构,也意味着你实际上没有看到错误信息。

在coredump的回溯中,您可能会看到对Perl_croak或Perl_vcroak的实际错误调用。

该perl错误的唯一解决方法是在程序退出时自己释放数据结构(例如,在退出之前自己解决全局变量)。如果你不能这样做(例如因为你不知道它是:),你可以自己捕获运行时错误(通过将代码包装到eval中)而不是正常退出程序,你可以打印错误并调用例如,POSIX :: _退出1。

使用AnyEvent :: Debug会将所有观察者回调包装到eval中并报告错误,这可能是一个开始。