2012-10-26 51 views
1

我正在将一些cgi脚本转换为mod_perl。在CGI下,我使用sig DIE来捕获堆栈跟踪,并在每次发生未捕获的异常时对其进行记录。这很有效:每当脚本中有东西死掉,我就会在应用程序日志中获得一个很好的堆栈跟踪。代码是:捕获与mod_perl异常的堆栈跟踪

BEGIN { 
    $SIG{__DIE__} = \&sigDie; 
} 

sub sigDie { 
    return 1 if $^S; # we are in an eval block 

    my ($error) = @_; 
    cluck("Caught fatal error: $error"); # put a stack trace in the logs via warn 
    local $Log::Log4perl::caller_depth = $Log::Log4perl::caller_depth + 1; 
    FATAL @_; # call log4perl's fatal 

    return 1; 
} 

在Apache2 :: Registry,然而,我的代码不再调用,它只是停止,当它死亡记录。我认为这是因为我的代码正在被mod_perl评估,但我把上面的例程取消了eval check,而且我还没有被调用。

有什么办法可以在mod_perl下得到我想要的吗?我发现这些堆栈痕迹的自动记录非常有用,如果我不得不放弃它们,会错过它们。到目前为止,我已经对如何得到它空了。

+1

FWIW信号处理程序的返回值无效。不妨''回来;'以避免读者认为它确实如此。 – Schwern

+0

谢谢,会更新它。不记得我为什么这么做了。 – mvsjes2

回答

1

我不知道答案,但可以想到一些可能性和方法来检查。

  • log4perl有问题。

拨打FATAL是否仍在__DIE__处理程序之外工作?

  • 根本没有记录错误。

删除死处理程序,做异常记录?

  • 东西正在取代您的$SIG{__DIE__}处理程序。

由于您将其设置为BEGIN时间,因此可能是Apache2 :: Registry或其他程序中的某个内容替换了它。通过在发现错误之前验证$SIG{__DIE__}中的内容,我会发现它。也许倾销与Data::Dump::Streamer,它可以处理代码参考,你可能会弄清楚是什么设置它。

一个更安全,更有礼貌,方式,注册一个模处理程序...

local $SIG{__DIE__} = ...; 

...the rest of your program... 

这将重新注册的每个请求处理程序,而不是吹在全球处理的范围之外。

希望能帮助我们弄清楚发生了什么。