1

我正在将一些 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 评估,但我在上面的例程中取消了评估检查,但我仍然没有被调用。

有什么办法可以在 mod_perl 下得到我想要的东西?我发现这些自动记录堆栈跟踪非常有用,如果我不得不放弃它们,我会错过它们。到目前为止,我对如何获得它一无所知。

4

1 回答 1

1

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

  • log4perl 出了点问题。

调用是否FATAL仍然在__DIE__处理程序之外工作?

  • 根本没有记录错误。

移除模具处理程序,是否记录异常?

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

由于您正在设置它BEGIN,因此 Apache2::Registry 或其他程序中的某些东西可能正在替换它。我会通过$SIG{__DIE__}在抛出错误之前验证其中的内容来找出答案。也许使用可以处理代码引用的Data::Dump::Streamer将其转储出来,您也许能够弄清楚是什么设置了它。

注册模具处理程序的一种更安全、更有礼貌的方法是……

local $SIG{__DIE__} = ...;

...the rest of your program...

这将在每个请求上重新注册您的处理程序,并且不会超出其范围之外的全局处理程序。

希望这有助于弄清楚发生了什么。

于 2012-10-26T23:43:59.157 回答