Practical mod_perlPractical mod_perlSearch this book

Chapter 22. Troubleshooting mod_perl

Contents:

Configuration and Startup
Code Parsing and Compilation
Runtime
Shutdown and Restart

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:

  1. Search for the line LD_RUN_PATH=

  2. 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.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.