intermittent "Undefined subroutine" with mod_perl


M

Moulin Kluge

Hello,

I'm running a mod_perl application that works ok for a couple of
hours, but after a while I start getting an intermittent error:

Software error:

Undefined subroutine
&ModPerl::ROOT::ModPerl::Registry::var_www_cgi_2dbin_request_requestlist_2epl::printHeaders
called at /var/www/cgi-bin/request/requestlist.pl line 30.

It appears to only happen on a single thread, and when I hit this
thread, then I get the error. I'm running Redhat 9, completely
updated with Apache 2.0.40, mod_perl 1.99, and the latest update from
CPAN of CGI.pm.

I have multiple projects that use customized version of the same
private module, which doesn't really work with the latest mod_perl and
apache, because mod_perl scripts no longer have the current directory
set to the same as the script location, so I added the following to
the top of the scripts so that I can use my private modules:

BEGIN {
if( $ENV{"SCRIPT_FILENAME"} && $ENV{"SCRIPT_FILENAME"} =~
/^(.+)\/[^\/]+$/ )
{
chdir $1;
}
# Set library paths in @INC, at compile time
unshift @INC, '.';
}

The PrintHeaders function that is declared as "Undefined" above is in
the module. Is there possibly something weird going on here where one
of the threads perhaps ignoring this code? I know that this is not
the best way to handle modules (as opposed to putting them in the @INC
dirs), but it is really useful in a development environment.

Any help is appreciated. Thank you.

Eli
 
Ad

Advertisements

B

Brian McCauley

I'm running a mod_perl application that works ok for a couple of
hours, but after a while I start getting an intermittent error:

Software error:

Undefined subroutine
&ModPerl::ROOT::ModPerl::Registry::var_www_cgi_2dbin_request_requestlist_2epl::printHeaders
called at /var/www/cgi-bin/request/requestlist.pl line 30.

This is usually an effect of using Perl4-style libraries within
mod_perl. Don't do that. If you have a legacy library you have to
use then wrap it in a Perl5-style library (i.e. and module that uses
exporter).
I have multiple projects that use customized version of the same
private module, which doesn't really work with the latest mod_perl and
apache, because mod_perl scripts no longer have the current directory
set to the same as the script location,

I think you'll find it never really worked - perhaps you were
(unknowingly) already using kludge mentioned below.
so I added the following to
the top of the scripts so that I can use my private modules:

BEGIN {
if( $ENV{"SCRIPT_FILENAME"} && $ENV{"SCRIPT_FILENAME"} =~
/^(.+)\/[^\/]+$/ )
{
chdir $1;
}
# Set library paths in @INC, at compile time
unshift @INC, '.';
}

Oh, so that would be your problem. Don't do that (muck about with
@INC) either.

The major point of mod_perl Registry is to only have to load each
module once rather than once per script. Once a module called Foo is
loaded no other module called Foo will be loaded by the same
interpreter thread.
The PrintHeaders function that is declared as "Undefined" above is in
the module. Is there possibly something weird going on here where one
of the threads perhaps ignoring this code? I know that this is not
the best way to handle modules (as opposed to putting them in the @INC
dirs), but it is really useful in a development environment.

There are features mod_perl that allow different areas of the server
to effectively have different @INC (Apache::perlVINC). It works by
reloading modules. This is intended as a development environment tool
- it's not something you'd want in a production environment. Be aware
that not all modules can be reloaded with impunity. Some will leak
memory. Some will do worse things.

In the case of a production environment ISTR that you can (in mod_perl2)
have multiple Perl interpreter pools and use different pools for
different areas of your website. (But then again do you really want
mod_perl2 in a production environment yet?).

--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
 
Ad

Advertisements

P

pkent

BEGIN {
if( $ENV{"SCRIPT_FILENAME"} && $ENV{"SCRIPT_FILENAME"} =~
/^(.+)\/[^\/]+$/ )
{
chdir $1;
}

BEGIN blocks are executed at compile time. As you know, compilation
happens once under mod_perl.

Also the environment and cwd is reset on each request.

You don't paste any code but I suspect that this is related to the
problem - if you show us the relevant bit it might shed light on a
different place though. Personally though I think the chdir is not how
I'd do it, I'd do:

#### begin program.pl
use strict;
use lib '/home/moulin/lib';
use PrivateModule;

# some code

PrivateModule::thingy( $foo );
####################

or some variant with importing, or OO or whatever appropriate to the
task in hand.

P
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top