home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Practical mod_perlPractical mod_perlSearch this book

Chapter 22. Troubleshooting mod_perl

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