【问题标题】:perl coro segmentation faultperl coro 分段错误
【发布时间】:2013-12-29 08:56:59
【问题描述】:

我有一个使用 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 次)它会因分段错误错误而失败。

它可能是什么错误,我如何检测它?

【问题讨论】:

    标签: perl segmentation-fault


    【解决方案1】:

    如果没有回溯(例如来自核心转储),很难说出原因,因为您没有提供有关崩溃位置的信息。

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

    使用大量回调代码(例如使用 AnyEvent 或 Coro 的代码)创建循环数据结构稍微容易一些。

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2015-08-31
      • 1970-01-01
      • 2013-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-10
      • 2012-08-12
      相关资源
      最近更新 更多