Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Variable will not stay shared in a sporadically crashing CGI

by Locutus (Beadle)
on Oct 02, 2017 at 12:46 UTC ( #1200516=perlquestion: print w/replies, xml ) Need Help??
Locutus has asked for the wisdom of the Perl Monks concerning the following question:

Dear Fellow Monks,

please, have a look at the following quite minimalistic CGI program:

#!/usr/bin/perl use strict; use warnings; use CGI; my $cgi = new CGI; print_document_header(); print_document(); ###################################################################### sub print_document_header { ###################################################################### print $cgi->header( -type => 'text/html' ), "\n"; } ###################################################################### sub print_document { ###################################################################### print $cgi->start_html( -dtd => '-//W3C//DTD HTML 4.01 Transitional//EN', -title => 'Hello, world!', ), "\n", $cgi->p( 'Hello, world!' ), "\n", $cgi->end_html(); }

I have three questions regarding this program:

  1. Whenever this program runs I get the warnings Variable "$cgi" will not stay shared referring to lines 15 and 22. Of course, I consulted perldiag in order to learn more about this kind of warning but - just like each of the other pages I found by searching the web for it - perldiag only talks about "an inner (nested) named subroutine ... referencing a lexical variable defined in an outer named subroutine". So where am I nesting named subroutines in my program? I only see two separate subroutines in a main program.
  2. When running this CGI under Apache/2.2.31 (Unix), mod_perl/2.0.8, Perl/v5.10.1 I see it working as expected the first few times I reload the request but after some (varying) number of reloads it crashes with a segmentation fault! What's happening there?
  3. By trial-and-error I found that it makes the program perfectly stable if I pass $cgi to the print_document_header subroutine as a parameter, i.e. calling print_document_header( $cgi ) with
    ###################################################################### sub print_document_header { ###################################################################### my $cgi = shift @_; print $cgi->header( -type => 'text/html' ), "\n"; }
    Why is it sufficient to pass $cgi only to the subroutine which calls $cgi->header and simply use the "global" $cgi in any other subroutine?

Humble thanks for your adwise in advance!

Replies are listed 'Best First'.
Re: Variable will not stay shared in a sporadically crashing CGI
by Corion (Pope) on Oct 02, 2017 at 12:54 UTC

    Apache resp. mod_perl is wrapping your CGI script in a subroutine to repeatedly call it. This also explains why you have the problem with the "global" lexical $cgi.

    Your workaround of explicitly passing around the variable is a good one in my opinion.

      Apache resp. mod_perl is wrapping your CGI script in a subroutine to repeatedly call it.
      This is the right explanation, but maybe the meaning is not completely clear. When you use Apache::Registry to run your script, it literally adds a set of brackets around your script and makes the whole thing into a sub, kind of like this:
      sub handler { #!/usr/bin/perl use strict; use warnings; use CGI; my $cgi = new CGI; print_document_header(); sub print_document_header { print $cgi->header( -type => 'text/html' ), "\n"; } }
      Your workaround of explicitly passing around the variable is a good one in my opinion.
      I completely agree, but if you're allergic to good programming practice you can just use our $cgi instead of my $cgi.
        you can just use our $cgi instead of my $cgi

        Locutus: Please, avoid globals - the "best" way to do it is to pass $cgi as an argument to the subroutines.

Re: Variable will not stay shared in a sporadically crashing CGI (updated)
by LanX (Bishop) on Oct 02, 2017 at 12:58 UTC
Re: Variable will not stay shared in a sporadically crashing CGI (Fast CGI)
by LanX (Bishop) on Oct 02, 2017 at 14:29 UTC
    On a side note: From my experience it's much easier to migrate a "simple" CGI to Fast CGI than Mod Perl.

    Investing into even newer* solutions would pay off in the log run.

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

    *) i.e. PSGI or even Mojolicious or Dancer

Re: Variable will not stay shared in a sporadically crashing CGI
by stevieb (Abbot) on Oct 02, 2017 at 16:01 UTC

    This was posted to an incorrect thread, one that I can not reparent it to.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1200516]
Approved by Corion
Front-paged by haukex
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2017-10-21 05:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My fridge is mostly full of:

















    Results (269 votes). Check out past polls.

    Notices?