When something goes wrong, we expect the software to report the
problem. But if we don't understand the meaning of
the error message, we won't be able to resolve it.
Therefore in this chapter we will talk about errors specific to
mod_perl, as reported by a mod_perl-enabled Apache server.
Many reports are produced by Perl itself. If you find them unclear,
you may want to use the use diagnostics pragma in
your development code. With the diagnostics
pragma, Perl provides an in-depth explanation of each reported
warning and error. Note that you should remove this pragma in your
production code, since it adds a runtime overhead.
Errors that may occur during the build and installation stages are
covered in the respective troubleshooting sections of Chapter 3. This chapter deals with errors that may occur
during the configuration and startup, code parsing and compilation,
runtime, and shutdown and restart phases.
22.1. Configuration and Startup
This section covers errors you might encounter when
you start the server.
22.1.1. libexec/libperl.so: open failed: No such file or directory
If you get this error when you start
the server, it probably
means that your version of Perl was itself compiled with a shared
library called libperl.so. mod_perl detects this
and links the Apache executable to the same Perl shared library. This
error simply means that the shared library cannot be found by
searching the paths that Apache knows about.
Make sure you have Perl installed on the machine, and that you have
libperl.so in
<perlroot>/<version>/<architecture>/CORE
(for example,
/usr/local/lib/perl5/5.6.1/sun4-solaris/CORE).
If the file is there but you still get the error, you should include
the directory in which the file is located in the environment
variable LD_LIBRARY_PATH (or the equivalent
variable for your operating system). Under normal circumstances,
Apache should have had the library path configured properly at
compile time; if Apache was misconfigured, adding the path to
LD_LIBRARY_PATH manually will help Apache find the
shared library.
22.1.2. install_driver(Oracle) failed: Can't load `.../DBD/Oracle/Oracle.so' for module DBD::Oracle
Here's an example of the full error
report that you might see:
install_driver(Oracle) failed: Can't load
'/usr/lib/perl5/site_perl/5.6.1/i386-linux/auto/DBD/Oracle/Oracle.so'
for module DBD::Oracle:
libclntsh.so.8.0: cannot open shared object file:
No such file or directory at
/usr/lib/perl5/5.6.1/i386-linux/DynaLoader.pm line 169.
at (eval 27) line 3
Perhaps a required shared
library or dll isn't installed where expected at
/usr/local/apache/perl/tmp.pl line 11
On BSD-style filesystems, LD_LIBRARY_PATH is not
searched for setuid programs. If Apache is a
setuid executable, you might receive this error.
Therefore, the first solution is to explicitly load the library from
the system-wide ldconfig configuration file:
panic# echo $ORACLE_HOME/lib >> /etc/ld.so.conf
panic# ldconfig
Another solution to this problem is to modify the
Makefile file (which is created when you run
perl Makefile.PL) as follows:
-
Search for the line LD_RUN_PATH=
-
Replace it with LD_RUN_PATH=my_oracle_home/lib
where my_oracle_home is, of course, the home
path to your Oracle installation. In particular, the file
libclntsh.so.8.0 should exist in the
lib subdirectory.
Then just type make install, and all should go
well.
Note that setting LD_RUN_PATH has the effect of
hardcoding the path to my_oracle_home/lib in the
file Oracle.so, which is generated by
DBD::Oracle. This is an efficiency mechanism, so
that at runtime it doesn't have to search through
LD_LIBRARY_PATH or the default directories used by
ld.
For more information, see the ld manpage and the
essay on LD_LIBRARY_PATH at http://www.visi.com/~barr/ldpath.html.
22.1.3. Invalid command `PerlHandler'...
Here's an example of the full error
report that you might see:
Syntax error on line 393 of /home/httpd/httpd_perl/conf/httpd.conf:
Invalid command 'PerlHandler', perhaps mis-spelled or
defined by a module not included in the server
configuration [FAILED]
You might get this error when you have a mod_perl-enabled Apache
server compiled with DSO, but the mod_perl module
isn't loaded. (This generally happens when
it's an installed RPM or other binary package.) In
this case you have to tell Apache to load mod_perl by adding the
following line to your httpd.conf file:
AddModule mod_perl.c
You might also get this error when you try to run a non-mod_perl
Apache server using the httpd.conf file from a
mod_perl server.
22.1.4. RegistryLoader: Translation of uri [...] to filename failed
Here's an example of the full error
report that you might see:
RegistryLoader: Translation of uri
[/home/httpd/perl/test.pl] to filename failed
[tried: /home/httpd/docs/home/httpd/perl/test.pl]
In this example, this means you are trying to preload a script called
/perl/test.pl, located at
/home/httpd/perl/test.pl in the filesystem. This
error shows up when Apache::RegistryLoader fails
to translate the URI into the corresponding filesystem path. Most
failures happen when a user passes a file path (such as
/home/httpd/perl/test.pl) instead of a relative
URI (such as /perl/test.pl).
You should either provide both the URI and the filename:
Apache::RegistryLoader->new->handler($uri, $filename);
or supply a callback subroutine that will perform the URI-to-filename
conversion. The callback accepts the URI as an argument and returns a
filename. For example, if your mod_perl scripts reside in
/home/httpd/perl-scripts/ but the base URI is
/perl/, you might do the following:
my $rl = Apache::RegistryLoader->new(
trans => \&uri2filename);
$rl->handler("/perl/test.pl");
sub uri2filename{
my $uri = shift;
$uri =~ s:^/perl/:/perl-scripts/:;
return Apache->server_root_relative($uri);
}
Here, we initialize the Apache::RegistryLoader
object with the uri2filename( ) function that will
perform the URI-to-filename translation. In this function, we just
adjust the URI and return the filename based on the location of the
server root. So if the server root is
/home/httpd/, the callback will return
/home/httpd/perl-scripts/test.pl—exactly
what we have requested.
For more information please refer to the
Apache::RegistryLoader manpage.