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.
I don’t know the answer, but can think of a few possibilities and ways to check.
Does a call to
FATALstill work outside of a__DIE__handler?Remove the die handler, do exceptions get logged?
$SIG{__DIE__}handler.Since you’re setting it up at
BEGINtime, 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…
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.