我使用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;
不时(例如一天中的一次)它会因分段错误错误而失败。
它有什么错误,如何检测它?
答案 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中并报告错误,这可能是一个开始。