我正在将一些cgi脚本转换为mod_perl。在cgi下,我使用sig DIE捕获堆栈跟踪,只要存在未捕获的异常,并记录它们。这非常有效:每当脚本中出现问题时,我的应用程序日志中都会有一个很好的堆栈跟踪。代码是:
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检查,但我仍然没有被调用。
有什么方法可以在mod_perl下得到我想要的东西吗?我发现堆栈跟踪的这些自动记录非常有用,如果我不得不放弃它们会错过它们。到目前为止,我已经找不到如何获得它。
答案 0 :(得分:1)
我不知道答案,但可以想到一些可能性和方法来检查。
对FATAL
的调用是否仍在__DIE__
处理程序之外?
删除模具处理程序,是否记录异常?
$SIG{__DIE__}
处理程序。由于您在BEGIN
时间进行设置,因此Apache2 :: Registry或其他程序中的某些内容可能会替换它。我会在抛出错误之前通过验证$SIG{__DIE__}
中的内容来找出答案。或许可以使用Data::Dump::Streamer将其转储出来,它可以处理代码引用,你或许可以弄清楚是什么设置它。
注册模具处理程序的更安全,更礼貌的方式是......
local $SIG{__DIE__} = ...;
...the rest of your program...
这将在每个请求上重新注册您的处理程序,而不是超出其范围之外的全局处理程序。
希望有助于弄清楚发生了什么。