Inconsistent and inexplicable behavior in some perl files

The host is Linux. I have several files in one directory. All *.pl files contain the following at the beginning, differing only in comments:

 #!/usr/bin/perl -w BEGIN { chdir('/home/httpd/vhosts/mysite.com/httpdocs/newsbot'); unshift(@INC, "/home/httpd/vhosts/mysite.com/httpdocs/newsbot"); } use Form; use File; use Mysite; #Read in All Form Variables &ReadInForm; 

The Form.pm file contains the ReadInForm routine and nothing more.

 sub ReadInForm { } 1; 

The strange thing is that the output of the above is completely contradictory. Sometimes it runs fine, but it displays the message “Internal server error” at the end of the script and puts the following in the error_log file:

The argument "is not numeric in the routine entry in / usr / lib 64 / perl5 / vendor_perl / 5.8.8 / x86_64-linux-thread-multi / ModPerl / RegistryCooker.pm line 171. \ n, referer: http: // www. mysite.com/newsbot/groupkeywords.pl

In other cases, it fails and displays the following in the browser:

Undefined subroutine & ModPerl :: ROOT :: ModPerl :: Registry :: home_httpd_vhosts_mysite_2ecom_httpdocs_newsbot_groupkeywords_2epl :: ReadInForm is called in /home/httpd/vhosts/mysite.com/httpdocs/nkeys/newspl

In other cases, it works correctly without errors.

It is strange that this is inconsistent. I can get one result from the file, update a few minutes later, and then get another. I even have a few "Internal Server Error" messages and 500 response headers, with no actual content. Commenting a line &ReadInForm; solves the problem every time, so I narrowed it down to this, however it doesn’t matter what I entered in Form.pm I can even put in an empty subroutine (like I already above), and it still does not solve the problem.

I'm not even sure how to debug this. How is it possible for it to be inconsistent? Does the perl compiler do caching behind the scenes?

+4
source share
2 answers

Obviously your host uses Apache mod_perl. You must explicitly specify the code for mod_perl. By the way, your code smells of perl 4 and cgi-lib.pl, 1996. Simply put, in mod_perl your script cannot work, because global variables are completely forbidden and you cannot change @INC in mod_perl anyway. Better put " use strict; use warnings; " in your script and use the correct CGI or mod_perl parsing modules and functions.

However, this code style should work:

 #!/usr/bin/perl # I don't know what this BEGIN block is for, but I suspect it may not work or causes subtle bugs... BEGIN { chdir('/home/httpd/vhosts/mysite.com/httpdocs/newsbot'); } use strict; use warnings; use Form; use File; use Mysite; #Read in All Form Variables Form::ReadInForm(); 

With this in Form.pm:

 use strict; use warnings; package Form; sub ReadInForm { } 1; 

Change If your code is out of date and you want to save some overhaul, you can create a "main" sub containing all the script code and variable declarations, and just call it this:

Old script:

 #!/usr/bin/perl # the following line will fail with "undeclared variable" under "use strict" $a="test"; print "$a\n"; 

New script:

 #!/usr/bin/perl use strict; use warnings; # call the main loop enclosing everything else main(); sub main { # first declare all variables my $a; # then add there all the code: $a="test"; print "$a\n"; } 

Thus, the script can be “upgraded” cheaply and very quickly.

+5
source

At this later date in 2017, I have one thing to add to this topic based on my recent similar experience. It is obvious to me that the old obsolete Perl code of 1990 should experience strange errors when running in mod_perl, as clearly and briefly explained in ( http://www.fifi.org/cgi-bin/man2html/usr/share/man/ man3 / mod_perl_traps.3pm.gz ). Other documentation also shows that mod_perl was created to speed up perl server code up to 35 times due to thread reuse, but some old Perl CGI methods should be avoided to make this work clean.

Which is theoretically BIG! But not always ...

My one caveat is the perl_mod community of guru enthusiasts. When you decide how to run obsolete perl, don’t automatically suggest using mod_perl and thus force a consistent set of unexpected code changes on unsuspecting obsolete perl code.

Instead, first determine if the executable should work at its maximum efficiency (in a reusable reusable environment), or if the very good old-fashioned single-stream CGI.

Like in my case. In 1998, I wrote a very small CGI perl on-line ordering system. One of the first of its kind. Now (in 2017), I wanted to deploy it simply to demonstrate the old code that I wrote (for example, a resume element). It will never be launched except as a demonstration.

So mod_perl is OVERKILL, but SysAdmins on my new hosting site insisted that I install mod_perl, which, as I understood it, was his common habit, but later it became clear that they really knew nothing about what mod_perl does for the old CGI perl system. But at that time I wasn’t either. So, I did as they asked, and only then found out about the mod_perl errors when I fell into them one by one.

If I had not just loaded mod_perl, none of these errors would have occurred, since the standard server configuration was old-fashioned CGI.

Caveat Emptor.

0
source

Source: https://habr.com/ru/post/1388891/


All Articles