Capturing stack traces on exceptions with mod_perl
Frage
I am converting some cgi scripts to mod_perl. Under cgi, I used a sig DIE to capture stack traces whenever there was an uncaptured exception, and logged them. This worked great: whenever something died in the script, I'd get a nice stack trace in my application logs. Code is:
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;
}
Under Apache2::Registry, however, my code is no longer called, it simply stops logging when it dies. I assumed this was because my code is being eval'ed by mod_perl, but I took the eval check off my routine above and I'm still not getting called.
Is there any way I can get what I want under mod_perl? I have found these automatic logging of stack traces immensely useful and would miss them if I have to forgo them. So far I have come up empty on how to get it.
Lösung
I don't know the answer, but can think of a few possibilities and ways to check.
- Something is wrong with log4perl.
Does a call to FATAL
still work outside of a __DIE__
handler?
- Errors are not being logged at all.
Remove the die handler, do exceptions get logged?
- Something is replacing your
$SIG{__DIE__}
handler.
Since you're setting it up at BEGIN
time, it's possible something either in Apache2::Registry or another program is replacing it. I'd find out by verifying what is in $SIG{__DIE__}
just before throwing an error. Perhaps dumping it out with Data::Dump::Streamer, which can handle code refs, you might be able to figure out what's setting it.
A safer, and more polite, way to register a die handler is...
local $SIG{__DIE__} = ...;
...the rest of your program...
This will re-register your handler on each request AND not blow over a global handler outside of its scope.
Hope that helps to figure out what's going on.