Here's a fun little issue me and my co-workers have been fighting for the past few months and was interested to see if anyone else out there had seen this, found a solution, etc.
The problem is...
In mod_perl 2.0.58 on Apache 2.0.x, when a Perl module is bound to a mod_perl event (ie
ChildInitHandler, for example) and the compilation of the referenced Perl module dies; mod_perl seems to hide the error (no logs, no STDERR, no nothing!) yet will still stop the Perl compilation. However, not assigned to an event and asked to compile through the
PerlModule pragma, it will die loudly as expected. Given an application be built in OO Perl, this can make for some *really* crazy bugs. Here's an example of what I'm trying to say here...
# httpd.conf
#
# Amongst other things that would normally be in the
# configuration
# Using PerlModule directive would work fine,
# commented here to try and be a bit more clear
# PerlModule Some::Module
# The module will die in compilation, but mod_perl
# doesn't seem to care at all
ChildInitHandler Some::Module
# lib/Some/Module.pm
package Some::Module;
use strict;
use warnings;
# Follow this chain here, the problem isn't
# truly within the handler, just when a module
# is bound to an event handler
use Another::Module::Bar;
sub handler {
1;
}
1;
# lib/Another/Module.pm
package Another::Module;
use strict;
use warnings;
sub new { bless {}, shift }
sub override_me {
print q/Not overridden/;
}
# lib/Another/Module/Bar.pm
package Another::Module::Bar;
use strict;
use warnings;
# The usage of the base module works fine
# where the 'Another::Module' module's
# method stash has successfully been attached
# to this module
use base qw( Another::Module );
die( q/This is an example of death from Perl/ );
sub override_me {
print q/Now it has been overridden/;
}
1;
Given the example above,
ChildInitHandler will 'use'
Some::Module, where
Some::Module will 'use'
Another::Module::Bar. Given there is an explicit
die() in this example
after the
use base will expose the situation:
- base will attach all methods to the calling package
- The explicit die() will stop compilation
- mod_perl will not say a word about the die
- If the Another::Module::Bar->override_me() method is then ever called, it will print Not overriden rather than Now it has been overridden
This is a pretty straight forward example, yet you may start to see the 'bugs' that will crop up when your entire application may or may not completely compile as you expected it.
Thoughts? Experiences?
Thanks!
---------
perl -le '$.=[qw(104 97 124 124 116 97)];*p=sub{[@{$_[0]},(45)x 2]};*d=sub{[(45)x 2,@{$_[0]}]};print map{chr}@{p(d($.))}'