Mailing List Archive

Prototype Mismatch in ModPerl::PerlRun
Greetings,

I'm investigating short term solutions for site performance (long term
is a full rewrite of the app) and I'm working for the first time with
ModPerl::PerlRun (and ModPerl::PerlRunPrefork, both seem to exhibit the
same behavior) and feel like I'm missing something obvious.

I have this reduction (as test2.pl):

####################
#!/usr/bin/perl

use strict;
use warnings;

use Time::HiRes qw(time);

use CGI;
my $cgi = CGI->new();

print $cgi->header();
print "<h1>Hello World</h1>\n";
print "<h1>HiRes time is: ", time(), "</h1>\n";
#####################

The script runs properly as far as I can see, but I'm getting Prototype
Mismatch warnings in the log with each hit after the first one:

Prototype mismatch: sub
ModPerl::ROOT::ModPerl::PerlRunPrefork::var_www_test_test2_2epl::time:
none vs () at /var/www/test/test2.pl line 6.

Other tests reveal it seems to happen pretty much anytime I import
something from a module into the script. I also tried loading
Time::HiRes into the startup (with and without the qw(time) import) and
it didn't make a difference; still get the error the first time I run
the script. If I make a copy of the script (say test3.pl), it will do
the same thing: The first run of the script produces no warning (even
after I've run test2 multiple times), but second and subsequent runs do
produce the warning.

My test setup is pretty minimal; an empty startup script and this for my
config:

PerlModule ModPerl::PerlRunPrefork Apache2::Status
PerlRequire /etc/apache2/startup/empty_startup.pl
<Location /perl-status>
SetHandler perl-script
PerlResponseHandler Apache2::Status
PerlSetVar StatusOptionsAll On
Require ip 127.0.0.1
</Location>
<VirtualHost *:443>
SSLEngine On
DocumentRoot /var/www/test
<Directory /var/www/test>
Options ExecCGI
AddHandler perl-script .pl
AllowOverride All
PerlResponseHandler ModPerl::PerlRunPrefork
Require all granted
</Directory>
</VirtualHost>

Have I configured or otherwise set something up wrong? I'd rather not
disable the warning and am puzzled as to what it's upset about.

mod_perl is version mod_perl/2.0.10 according to the perl-status
environment display, though ModPerl::PerlRun shows in the module list at
version 1.99 (don't know if that's expected or not). Apache is 2.4.38.

Thank you!

Dan
Re: Prototype Mismatch in ModPerl::PerlRun [ In reply to ]
Hi, Daniel. This error can happen even under regular Perl in some circumstances when a package redefines a core function ((like what importing Time::HiRes does here with time).

I would change "use Time::HiRes qw(time);" to "use Time::HiRes ();" and then change "time()" on line 13 to "Time::HiRes::time()." Does that make the message go away?

Even better would be to move or add "use Time::HiRes ();" to your startup.pl. I think it's generally a good idea (I want to say "best practice" even) to not import any functions or variables in your startup.pl, so I always add " ()" to my "use" statements there. You can then *usually* import specific functions with "use Whatever qw(func);" in your scripts. The problem here though is that the import is redefining the core function, and I think that can just be problematic.

I think the moral here is that ModPerl::PerlRun* is not a perfect drop-in replacement for a Perl CGI. With mod_perl, there's usually something you need to tweak (like how global variables and things like that) slightly in order to get it working as intended, but the changes are usually minor and make sense once you wrap your head around how mod_perl works.

Hope this helps!

Regards,
Ed

On May 14, 2021, at 9:36 AM, Daniel Ragle <daniel@Biblestuph.com> wrote:
> I'm investigating short term solutions for site performance (long term is a full rewrite of the app) and I'm working for the first time with ModPerl::PerlRun (and ModPerl::PerlRunPrefork, both seem to exhibit the same behavior) and feel like I'm missing something obvious.
>
> I have this reduction (as test2.pl):
>
> ####################
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> use Time::HiRes qw(time);
>
> use CGI;
> my $cgi = CGI->new();
>
> print $cgi->header();
> print "<h1>Hello World</h1>\n";
> print "<h1>HiRes time is: ", time(), "</h1>\n";
> #####################
>
> The script runs properly as far as I can see, but I'm getting Prototype Mismatch warnings in the log with each hit after the first one:
>
> Prototype mismatch: sub ModPerl::ROOT::ModPerl::PerlRunPrefork::var_www_test_test2_2epl::time: none vs () at /var/www/test/test2.pl line 6.
Re: Prototype Mismatch in ModPerl::PerlRun [ In reply to ]
Ed, thanks for your response!

I had already tried most of your suggestions: Putting the module load in
the startup (with or without the import) didn't make a difference (still
get the prototype mismatch on the second and subsequent runs of the
script); and yah, importing nothing and referring to the sub directly
via Time::HiRes::time() makes the error go away (presumably because
nothing is imported).

I had originally thought it would warn on any import, but after reading
your message I did a little more experimenting. It's true that not all
modules/routines will trigger the warning; as a test I just tried use
Digest::SHA qw(sha256) and it did not trigger the warning. However it
looks like it does happen for more than just overwritten CORE routines.
For example I can trigger the warning with use JSON qw(to_json); and use
Fcntl qw(:flock) generates the warning separately for each symbol imported.

Prototype mismatch: sub
ModPerl::ROOT::ModPerl::PerlRunPrefork::var_www_test_test5_2epl::LOCK_SH: none
vs () at /var/www/test/test5.pl line 8.
Prototype mismatch: sub
ModPerl::ROOT::ModPerl::PerlRunPrefork::var_www_test_test5_2epl::LOCK_NB: none
vs () at /var/www/test/test5.pl line 8.
Prototype mismatch: sub
ModPerl::ROOT::ModPerl::PerlRunPrefork::var_www_test_test5_2epl::LOCK_UN: none
vs () at /var/www/test/test5.pl line 8.
Prototype mismatch: sub
ModPerl::ROOT::ModPerl::PerlRunPrefork::var_www_test_test5_2epl::LOCK_EX: none
vs () at /var/www/test/test5.pl line 8.

Cheers!

Dan

On 5/14/2021 5:23 PM, Edward J. Sabol wrote:
> Hi, Daniel. This error can happen even under regular Perl in some circumstances when a package redefines a core function ((like what importing Time::HiRes does here with time).
>
> I would change "use Time::HiRes qw(time);" to "use Time::HiRes ();" and then change "time()" on line 13 to "Time::HiRes::time()." Does that make the message go away?
>
> Even better would be to move or add "use Time::HiRes ();" to your startup.pl. I think it's generally a good idea (I want to say "best practice" even) to not import any functions or variables in your startup.pl, so I always add " ()" to my "use" statements there. You can then *usually* import specific functions with "use Whatever qw(func);" in your scripts. The problem here though is that the import is redefining the core function, and I think that can just be problematic.
>
> I think the moral here is that ModPerl::PerlRun* is not a perfect drop-in replacement for a Perl CGI. With mod_perl, there's usually something you need to tweak (like how global variables and things like that) slightly in order to get it working as intended, but the changes are usually minor and make sense once you wrap your head around how mod_perl works.
>
> Hope this helps!
>
> Regards,
> Ed
>
> On May 14, 2021, at 9:36 AM, Daniel Ragle <daniel@Biblestuph.com> wrote:
>> I'm investigating short term solutions for site performance (long term is a full rewrite of the app) and I'm working for the first time with ModPerl::PerlRun (and ModPerl::PerlRunPrefork, both seem to exhibit the same behavior) and feel like I'm missing something obvious.
>>
>> I have this reduction (as test2.pl):
>>
>> ####################
>> #!/usr/bin/perl
>>
>> use strict;
>> use warnings;
>>
>> use Time::HiRes qw(time);
>>
>> use CGI;
>> my $cgi = CGI->new();
>>
>> print $cgi->header();
>> print "<h1>Hello World</h1>\n";
>> print "<h1>HiRes time is: ", time(), "</h1>\n";
>> #####################
>>
>> The script runs properly as far as I can see, but I'm getting Prototype Mismatch warnings in the log with each hit after the first one:
>>
>> Prototype mismatch: sub ModPerl::ROOT::ModPerl::PerlRunPrefork::var_www_test_test2_2epl::time: none vs () at /var/www/test/test2.pl line 6.
>
>
Re: Prototype Mismatch in ModPerl::PerlRun [ In reply to ]
Was wrong on one of my statements: use Digest::SHA qw(sha256) _does_
produce the warning, after all. And with use Time::HiRes qw(usleep
tv_interval) usleep produces the warning, but tv_interval does not.
tv_interval is directly defined in Time::HiRes, the rest is C code.
Maybe only XS loaded code triggers the warnings?

Cheers!

Dan

On 5/18/2021 3:26 PM, Daniel Ragle wrote:
> Ed, thanks for your response!
>
> I had already tried most of your suggestions: Putting the module load in
> the startup (with or without the import) didn't make a difference (still
> get the prototype mismatch on the second and subsequent runs of the
> script); and yah, importing nothing and referring to the sub directly
> via Time::HiRes::time() makes the error go away (presumably because
> nothing is imported).
>
> I had originally thought it would warn on any import, but after reading
> your message I did a little more experimenting. It's true that not all
> modules/routines will trigger the warning; as a test I just tried use
> Digest::SHA qw(sha256) and it did not trigger the warning. However it
> looks like it does happen for more than just overwritten CORE routines.
> For example I can trigger the warning with use JSON qw(to_json); and use
> Fcntl qw(:flock) generates the warning separately for each symbol imported.
>
> Prototype mismatch: sub
> ModPerl::ROOT::ModPerl::PerlRunPrefork::var_www_test_test5_2epl::LOCK_SH: none
> vs () at /var/www/test/test5.pl line 8.
> Prototype mismatch: sub
> ModPerl::ROOT::ModPerl::PerlRunPrefork::var_www_test_test5_2epl::LOCK_NB: none
> vs () at /var/www/test/test5.pl line 8.
> Prototype mismatch: sub
> ModPerl::ROOT::ModPerl::PerlRunPrefork::var_www_test_test5_2epl::LOCK_UN: none
> vs () at /var/www/test/test5.pl line 8.
> Prototype mismatch: sub
> ModPerl::ROOT::ModPerl::PerlRunPrefork::var_www_test_test5_2epl::LOCK_EX: none
> vs () at /var/www/test/test5.pl line 8.
>
> Cheers!
>
> Dan
>
> On 5/14/2021 5:23 PM, Edward J. Sabol wrote:
>> Hi, Daniel. This error can happen even under regular Perl in some
>> circumstances when a package redefines a core function ((like what
>> importing Time::HiRes does here with time).
>>
>> I would change "use Time::HiRes qw(time);" to "use Time::HiRes ();"
>> and then change "time()" on line 13 to "Time::HiRes::time()." Does
>> that make the message go away?
>>
>> Even better would be to move or add "use Time::HiRes ();" to your
>> startup.pl. I think it's generally a good idea (I want to say "best
>> practice" even) to not import any functions or variables in your
>> startup.pl, so I always add " ()" to my "use" statements there. You
>> can then *usually* import specific functions with "use Whatever
>> qw(func);" in your scripts. The problem here though is that the import
>> is redefining the core function, and I think that can just be
>> problematic.
>>
>> I think the moral here is that ModPerl::PerlRun* is not a perfect
>> drop-in replacement for a Perl CGI. With mod_perl, there's usually
>> something you need to tweak (like how global variables and things like
>> that) slightly in order to get it working as intended, but the changes
>> are usually minor and make sense once you wrap your head around how
>> mod_perl works.
>>
>> Hope this helps!
>>
>> Regards,
>> Ed
>>
>> On May 14, 2021, at 9:36 AM, Daniel Ragle <daniel@Biblestuph.com> wrote:
>>> I'm investigating short term solutions for site performance (long
>>> term is a full rewrite of the app) and I'm working for the first time
>>> with ModPerl::PerlRun (and ModPerl::PerlRunPrefork, both seem to
>>> exhibit the same behavior) and feel like I'm missing something obvious.
>>>
>>> I have this reduction (as test2.pl):
>>>
>>> ####################
>>> #!/usr/bin/perl
>>>
>>> use strict;
>>> use warnings;
>>>
>>> use Time::HiRes qw(time);
>>>
>>> use CGI;
>>> my $cgi = CGI->new();
>>>
>>> print $cgi->header();
>>> print "<h1>Hello World</h1>\n";
>>> print "<h1>HiRes time is: ", time(), "</h1>\n";
>>> #####################
>>>
>>> The script runs properly as far as I can see, but I'm getting
>>> Prototype Mismatch warnings in the log with each hit after the first
>>> one:
>>>
>>> Prototype mismatch: sub
>>> ModPerl::ROOT::ModPerl::PerlRunPrefork::var_www_test_test2_2epl::time: none
>>> vs () at /var/www/test/test2.pl line 6.
>>
>>