MyWebUniversity.com Home Page
 



Darwin Mac OS X man pages main menu
modperltraps(3)     User Contributed Perl Documentation    modperltraps(3)



NAME
       modperltraps - common/known modperl traps

DESCRIPTION
       In the CGI environment, the server starts a single external process
       (Perl interpreter) per HTP request which runs single script in that
       process space.  When the request is over, the process goes away every-
       thing is cleaned up and a fresh script is started for the next request.
       modperl brings Perl inside of the HTP server not only for speedup of
       CGI scripts, but also for access to server functionality that CGI
       scripts do not and/or cannot have.  Now that we're inside the server,
       each process will likely handle more than one Perl script and keep it
       "compiled" in memory for longer than a single HTP request.  This new
       location and longer lifetime of Perl execution brings with it some com-
       mon traps.  This document is here to tell you what they are and how to
       prevent them.  The descriptions here are short, please consult the
       modperl FAQ for more detail.  If you trip over something not docu-
       mented here, please send a message to the modperl list.

       igrating from CGI


       ]o   Be sure to have read cgitomodperl

       ]o   Scripts under Apache::Registry are not run in package main, they
           are run in a unique namespace based on the requested uri.

       ]o   Apache::Registry scripts cannot contain  END or DATA tokens

       ]o   Output of "system", "exec" and "open PIPE, "program"" calls will
           not be sent to the browser unless you Perl was configured with
           sfio.

       ]o   Perl's exit() built-in function cannot be used in modperl scripts.
           The Apache::exit() function should be used instead.  Apache::exit()
           automatically overrides the built-in exit() for Apache::Registry
           and Apache::PerlRun scripts.

       ]o   Your script *will not* run from the command line if your script
           makes any direct calls to Apache->methods.  See Apache::Fak-
           eRequest.

       Apache::::Registry


       undefined subroutine &Apache::Registry::handler
           Interaction with certain modules causes the shortcut configuration
           to break, if you see this message change your configuration from
           this:

            
            PerlHandler Apache::Registry
            ...
            

           To this:

            PerlModule Apache::Registry
            
            PerlHandler Apache::Registry::handler
            ...
            

       Using CGI.pm and CGI::::**


       ]o   CGI.pm users must have version 2.39 of the package or higher, ear-
           lier versions will not work under modperl.

       ]o   If you use the "SendHeaders()" function, be sure to call
           $reqobj->cgi->done when you are done with a request, just as you
           would under CGI::MiniSrv.

       Perl odules and Extensions


       ]o   Files pulled in via "use" or "require" statements are not automati-
           cally reloaded when changed on disk.  See the Apache::StatINC or
           the Apache::Reload module to add this functionality.

       Undefined subroutines
           A common trap with required files may result in an error message
           similar to this in the errorlog:

            [Thu Sep 11 11:03:06 1997] Undefined subroutine
            &Apache::ROT::perl::test2epl::somefunction called at
            /opt/www/apache/perl/test.pl line 79.

           As the above items explains, a file pulled in via "require" will
           only happen once per-process (unless %INC is modified).  If the
           file does not contain a "package" declaration, the file's subrou-
           tines and variables will be created in the current package.  Under
           CGI, this is commonly package "main".  However, Apache::::Registry
           scripts are compiled into a unique package name (base on the uri).
           So, if multiple scripts in the same process try to require the same
           file, which does not declare a package, only one script will actu-
           ally be able to see the subroutines.  The solution is to read
           perlmodlib, perlmod and related perl documentation and re-work your
           required file into a module which exports functions or defines a
           method interface.  Or something more simple, along these lines:

            #requiredfile.pl
            package Test;

            sub somefunction {...}

            ...

            END

           Now, have your scripts say:

            require "requiredfile.pl";

            Test::somefunction();

       Undefined subroutine &Foo::Bar::handler called at PerlHandler subrou-
       tine `Foo::Bar' line 1.
           You mistyped the module name in the 'package' line in your module.

       "Use of uninitialized value"
           Because of eval context, you may see warnings with useless file-
           name/line, example:

            Use of uninitialized value at (eval 80) line 12.
            Use of uninitialized value at (eval 80) line 43.
            Use of uninitialized value at (eval 80) line 44.

           To track down where this eval is really happening, try using a
           WARN handler to give you a stack trace:

            use Carp ();
            local $SIG{WARN} = \&Carp::cluck;

       "Callback called exit"
       "Out of memory!"
           If something goes really wrong with your code, Perl may die with an
           "Out of memory!" message and or "Callback called exit".  A common
           cause of this are never-ending loops, deep recursion or calling an
           undefined subroutine.  Here's one way to catch the problem: See
           Perl's INSTAL document for this item:

       -DPERLEMERGENCYSBRK
           If PERLEMERGENCYSBRK is defined, running out of memory need not
           be a fatal error: a memory pool can allocated by assigning to the
           special variable $^M.  See perlvar(1) for more details.

           If you compile with that option and add 'use Apache::Debug level =>
           4;' to your PerlScript, it will allocate the $^M emergency pool and
           the $SIG{DIE} handler will call Carp::confess, giving you a
           stack trace which should reveal where the problem is.

           See the Apache::::Resource module for prevention of spinning httpds.

       ]o   If you wish to use a module that is normally linked static with
           your Perl, it must be listed in staticext in Perl's Config.pm to
           be linked with httpd during the modperl build.

       Can't load '$Config{sitearchexp}/auto/Foo/Foo.so' for module Foo...
           When starting httpd some people have reported seeing an error along
           the lines of:

            [Thu Jul  9 17:33:42 1998] [error] Can't load
            '/usr/local/ap/lib/perl5/siteperl/sun4-solaris/auto/DBI/DBI.so' for
            module DBI: ld.so.1: src/httpd: fatal: relocation error: file
            /usr/local/ap/lib/perl5/siteperl/sun4-solaris/auto/DBI/DBI.so: symbol
            Perlsvundef: referenced symbol not found at
            /usr/local/ap/lib/perl5/sun4-solaris/5.00404/DynaLoader.pm line 166.

           Or similar for the IO module or whatever dynamic module modperl
           tries to pull in first.  The solution is to re-configure, re-build
           and re-install Perl and dynamic modules with the following flags
           when Configure asks for "additional LD flags":

            -Xlinker --export-dynamic

           or

            -Xlinker -E

           This problem is only known to be caused by installing gnu ld under
           Solaris.

           Other known causes of this problem:

           OS distributions that ship with a (broken) binary Perl installa-
           tion.

           The `perl' program and `libperl.a' library are somehow built with
           different binary compatiblity flags.

           The solution to these problems is to rebuild Perl and extension
           modules from a fresh source tree.  Tip for running Perl's Configure
           script, use the `"-des"' flags to accepts defaults and `"-D"' flag
           to override certain attributes:

            % ./Configure -des -Dcc=gcc ... && make test && make install

           Read Perl's INSTAL doc for more details.

       Clashes with other Apache C modules


       modauthdbm
           If you are a user of modauthdbm or modauthdb, you may need to
           edit Perl's "Config" module.  When Perl is configured it attempts
           to find libraries for ndbm, gdbm, db, etc., for the *DBM*File mod-
           ules.  By default, these libraries are linked with Perl and remem-
           bered by the Config module.  When modperl is configured with
           apache, the ExtUtils::::Embed module returns these libraries to be
           linked with httpd so Perl extensions will work under modperl.
           However, the order in which these libraries are stored in Con-
           fig.pm, may confuse "modauthdb*".  If "modauthdb*" does not
           work with modperl, take a look at this order with the following
           command:

            % perl -V:libs

           If "-lgdbm" or "-ldb" is before "-lndbm", example:

            libs='-lnet -lnsls -lgdbm -lndbm -ldb -ldld -lm -lc -lndir -lcrypt';

           Edit Config.pm and move "-lgdbm" and "-ldb" to the end of the list.
           Here's how to find Config.pm:

            % perl -MConfig -e 'print "$Config{archlibexp}/Config.pm\n"'

           Another solution for building Apache/modperl]modauthdbm under
           Solaris is to remove the DBM and NDBM "emulation" from libgdbm.a.
           Seems Solaris already provides its own DBM and NDBM, and there's no
           reason to build GDBM with them (for us anyway).

           In our Makefile for GDBM, we changed

             OBJS = $(DBMOF) $(NDBMOF) $(GDBMOF)

           to

             OBJS = $(GDBMOF)

           Rebuild libgdbm, then Apache/modperl.

REGULAR EXPRESIONS
       COMPILED REGULAR EXPRESIONS

       When using a regular expression that contains an interpolated Perl
       variable, if it is known that the variable (or variables) will not vary
       during the execution of the program, a standard optimization technique
       consists of adding the "o" modifier to the regexp pattern, to direct
       the compiler to build the internal table once, for the entire lifetime
       of the script, rather than every time the pattern is executed. Con-
       sider:

               my $pat = '^foo$'; # likely to be input from an HTML form field
               foreach( @list ) {
                       print if /$pat/o;
               }

       This is usually a big win in loops over lists, or when using "grep" or
       "map".

       In long-lived "modperl" scripts, however, this can pose a problem if
       the variable changes according to the invocation. The first invocation
       of a fresh httpd child will compile the table and perform the search
       correctly, however, all subsequent uses by the httpd child will con-
       tinue to match the original pattern, regardless of the current contents
       of the Perl variables the pattern is dependent on. Your script will
       appear broken.

       There are two solutions to this problem.

       The first is to use "eval q/", to force the code to be evaluated each
       time. Just make sure that the "eval" block covers the entire loop of
       processing, and not just the pattern match itself.

       The above code fragment would be rewritten as:

               my $pat = '^foo$';
               eval q{
                       foreach( @list ) {
                               print if /$pat/o;
                       }
               }

       Just saying

               eval q{ print if /$pat/o; };

       is going to be a horribly expensive proposition.

       You use this approach if you require more than one pattern match opera-
       tor in a given section of code. If the section contains only one opera-
       tor (be it an "m/" or "s/"), you can rely on the property of the
       null pattern, that reuses the last pattern seen. This leads to the sec-
       ond solution, which also eliminates the use of "eval".

       The above code fragment becomes:

               my $pat = '^foo$';
               "something" =~ /$pat/; # dummy match (MUST NOT FAIL!)
               foreach( @list ) {
                       print if /;
               }

       The only gotcha is that the dummy match that boots the regular expres-
       sion engine must absolutely, positively succeed, otherwise the pattern
       will not be cached, and the / will match everything. If you can't
       count on fixed text to ensure the match succeeds, you have two possi-
       bilities.

       If you can guaranteee that the pattern variable contains no meta-char-
       acters (things like "*", "]", "^", "$"...), you can use the dummy
       match:

               "$pat" =~ /\Q$pat\E/; # guaranteed if no meta-characters present

       If there is a possibility that the pattern can contain meta-characters,
       you should search for the pattern or the unsearchable "\377" character
       as follows:

               "\377" =~ /$pat^[\377]$/; # guarenteed if meta-characters present

       References

               The Camel Book, 2nd edition, p. 538 (p. 356 in the 1st edition).

AUTHORS
       Doug MacEachern, with contributions from Jens Heunemann , David Landgren , Mark Mills
       , Randal Schwartz  and Ask Bjoern
       Hansen 



perl v5.8.6                       2000-03-30                 modperltraps(3)
Darwin Mac OS X man pages main menu

Contact us      |       About us      |       Term of use      |       Copyright © 2000-2010 MyWebUniversity.com ™