Re: Moving ExecCGI to mod_perl - performance and custom'modules'[EXT]

André Warnier (tomcat/perl) <[email protected]>
Newsgroups gmane.comp.apache.mod-perl
Message-ID <[email protected]>
On 08.02.2021 10:09, Steven Haigh wrote:
> On Sun, Feb 7, 2021 at 15:17, Chris <[email protected]> wrote:
>> Just remember to always write clean code that resets variables after doing tasks.
> 
> I'm a bit curious about this - whilst I'm still testing all this on a staging environment, 
> how can I tell if things can leak between runs?
> 
> Is coding to normal 'use strict; use warnings;' standards good enough?

Hi. Read this, carefully :
http://perl.apache.org/docs/2.0/user/troubleshooting/troubleshooting.html#Variable__x_will_not_stay_shared_at

In particular the example below "An Easy Break-in".
(and replace
use vars ($authenticated);
by
our $authenticated;
)

("use vars" is deprecated, see https://perldoc.perl.org/vars)

The point is :
- imagine an Apache Prefork starting 5 children
- each child, when it starts, contains its own fresh copy of the perl interpreter
- requests which come in, are directed by the main Apache, to any child that is free at 
the time.
- when a child runs your script/module for the first time (with its particular perl 
interpreter), the script/module gets compiled, and then run, and the compiled code is 
cached by the corresponding perl interpreter
- global variables (such as $authenticated here) get defined during compilation, so are 
part of the cached script/module code.
- so the first time an Apache child runs your script, $authenticated is defined, but 
"empty" (undef). Then when the script runs, it assigns a value to it, so it is no longer 
undef.
- the next time your script is run *by the same Apache child*, the cached compiled version 
of the script is used (*), which already has $authenticated defined, and the previous 
value (set by the previous run) is still in it.
However, if it happens that the next request is run by another "fresh" Apache child, that 
one (its own instance of the perl interpreter) does not yet have a pre-compiled version of 
your script, so it gets compiled again, and in that instance $authenticated gets defined 
again, empty.

Since you cannot control which Apache child runs your script the next time you issue a 
request, the result may appear random (as far as $authenticated is concerned).

This "feature" can sometimes be very useful as an optimisation (for example, if you want 
to initialise a complex read-only structure only once per Apache child life), but in the 
general case, it will lead to strange things happening if you are not careful.

So to answer your question : "> how can I tell if things can leak between runs?",
a quick answer would be : just *assume* that everything "leaks" between runs, and make 
sure that you initialise every variable in a known way, before using it.

mod_perl is great fun, and the ability to run perl scripts much faster is only the tip of 
the iceberg.  But like every fun thing, it has some minor quirks like that. Do not let 
them discourage you.

(*) that's the point, and that's why it is much faster

> 
> Are there other ways to confirm correct operations?
> 
> --
> Steven Haigh 📧 [email protected] <mailto:[email protected]>💻 https://www.crc.id.au 
> <https://www.crc.id.au/>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.