【问题标题】:Perl getting segmentation fault while timeout using alarmPerl 在使用警报超时时出现分段错误
【发布时间】:2019-09-28 22:22:34
【问题描述】:

我是第一次编写 Perl,互联网告诉我,如果我有一个长时间运行的 sql 查询,我可以使用警报。 我需要运行一个将在 Perl 中运行数小时的 SP,并且我想设置一个时间限制。 下面是我的代码的最后一步,但是当进程运行的时间超过我的超时时间时,我得到了分段错误,在这种情况下是 sleep(20)。日志显示它完成打印 ---1---- 然后分段错误。 我该如何解决这个问题?

我尝试将 sub DelRef{} 取出到单独的 .pl 中,并在第三行中注释 $db 部分以测试警报是否正常工作,并且一切正常。我很困惑哪一部分出了问题并导致了分段错误。

sub DelRef {
    print "starting defRefData\n";
    $db = new Sybapi($user, $password, $server, $margin_database);
    print "entering eval\n";
    my $timeout = 10;
    eval {
            local $SIG{ALRM} = sub { die "timeout\n" };
            print "inside eval now\n";
            alarm($timeout);
            print "---1----\n";
            #sleep(5); --working fine
            sleep(20); #not working, 
            #$db->exec_sql("exec CPN_Margins..clean_up_refData_db '$XrefCode'");
            print "----2----\n";
            alarm(0);
    };
    #alarm(0);
            print "out of eval\n";
    if($@)
    {
        #die unless $@ eq "timeout\n";
        if($@ =~ "timeout\n")
        {
        warn "Timed out!\n";
        #exit 0;
        }
        else{
                print $@;
        }
    }

}

&DelRef();
print "process is done\n";
$db->close();

【问题讨论】:

  • 可能是 Sybapi 中的 C 代码错误地处理了在某些系统调用期间发生信号时发生的错误。 (信号会导致阻塞系统调用返回 EINTR 给信号处理程序一个运行的机会。)
  • 我不确定你想从中得到什么。首先,您甚至没有提出任何问题。
  • 所以我不应该使用 Sybapi 吗?我想知道如何解决这个分段错误。
  • 如果您想要的不仅仅是“不要同时使用alarm 和 Sybapi”,您就是在问如何调试 C 代码。这远远超出了本网站的范围。

标签: perl segmentation-fault timeout alarm


【解决方案1】:

来自 perldoc (https://perldoc.perl.org/functions/alarm.html)-

混用闹钟和睡眠电话通常是错误的,因为 sleep 可以在您的系统内部实现并带有警报。

如果要实现超时,可以不用休眠来实现。只需按照链接中提到的示例进行操作即可。

编辑: 我这里加了-How to set timeout for a long running Sybase sp in Perl

【讨论】:

  • 这与问题无关。 OP 的sleep 显然不依赖于alarm,并且当使用sleep 而不是缓慢的数据库调用时,OP 并没有遇到他所问的问题。
猜你喜欢
  • 2020-06-25
  • 2017-06-06
  • 2017-08-26
  • 2018-06-18
  • 2019-05-10
  • 2018-02-15
  • 2016-01-15
  • 2011-01-14
  • 2013-01-03
相关资源
最近更新 更多