4

我正在使用一个使用我们自己的库的 perl cgi 脚本,它使用“no autovivification”编译指示。例如

/usr/lib/company/mysim.cgi:

#!/usr/bin/perl -w

use strict;
# ... other use
use Company::Module1;

/usr/lib/perl5/Company/Module1.pm

package Company::Module1;

no autovivification;
use strict;
use warnings;

大约 50% 的情况下,当访问 URL 以到达 cgi 脚本时,编译会失败并...

[Fri Dec 04 15:40:10.744901 2015] [:error] [pid 30455:tid 2961136448] Bareword "A_HINT_STRICT" not allowed while "strict subs" in use at /usr/lib/i386-linux-gnu/perl5/5.20/autovivification.pm line 144.\nBareword "A_HINT_WARN" not allowed while "strict subs" in use at /usr/lib/i386-linux-gnu/perl5/5.20/autovivification.pm line 144.\nBareword "A_HINT_FETCH" not allowed while "strict subs" in use at /usr/lib/i386-linux-gnu/perl5/5.20/autovivification.pm line 144.\nBareword "A_HINT_STORE" not allowed while "strict subs" in use at /usr/lib/i386-linux-gnu/perl5/5.20/autovivification.pm line 144.\nBareword "A_HINT_EXISTS" not allowed while "strict subs" in use at /usr/lib/i386-linux-gnu/perl5/5.20/autovivification.pm line 144.\nBareword "A_HINT_DELETE" not allowed while "strict subs" in use at /usr/lib/i386-linux-gnu/perl5/5.20/autovivification.pm line 144.\nCompilation failed in require at /usr/lib/company/mysim.cgi line 14.\nBEGIN failed--compilation aborted at /usr/lib/company/mysim.cgi line 14.\n

(取自 /var/log/apache2/ssl/error.log,因为此脚本位于 https 端口上)。

我的环境是: - debian jessie (8.2) - tomcat7 - apache2 (2.4) - perl 5.20.2 - libautovivification-perl 0.12-1+b1

我的问题是:

  1. 有没有人见过这个?由于“使用严格”编译指示,自动生存模块无法编译似乎很奇怪。

  2. 谁能解释编译错误的间歇性?更奇怪的是,cgi 有一半的时间无法编译,而另一半则工作正常(即运行并返回预期结果)。

谢谢你的时间。

2015 年 9 月 12 日:一些附加信息...

感谢大家的反馈。

没有显式创建线程,尽管这是在 apache 的上下文中,因此可能存在请求的线程化。

根本原因似乎是 XSLoader 中的故障。至少这个最小的工作示例......

package autovivification;

use 5.008_003;

use strict;
use warnings;

our $VERSION;
BEGIN {
 $VERSION = '0.12';
}

BEGIN {
 require XSLoader;
 XSLoader::load(__PACKAGE__, $VERSION);
}

my %bits = (
 strict => A_HINT_STRICT,
 warn   => A_HINT_WARN,
 fetch  => A_HINT_FETCH,
 store  => A_HINT_STORE,
 exists => A_HINT_EXISTS,
 delete => A_HINT_DELETE,
);

编译,而这

package autovivification;

use 5.008_003;

use strict;
use warnings;

our $VERSION;
BEGIN {
 $VERSION = '0.12';
}

#BEGIN {
# require XSLoader;
# XSLoader::load(__PACKAGE__, $VERSION);
#}

my %bits = (
 strict => A_HINT_STRICT,
 warn   => A_HINT_WARN,
 fetch  => A_HINT_FETCH,
 store  => A_HINT_STORE,
 exists => A_HINT_EXISTS,
 delete => A_HINT_DELETE,
);

失败并出现相同的错误。

所以,我会在 apache 日志中四处寻找加载错误......某处。

感谢你的宝贵时间。

2015 年 12 月 16 日:更新 - 已修复

根本原因是 mod_perl,再加上 apache 2.2 和 2.4 之间的(可能的)变化。脚本的 apache 配置,给它一个 /cgi-bin/script 的 ScriptAlias URI,发生在设置 URI /cgi-bin 以由 mod_perl 处理之前。在 apache 2.2 中,这种排序似乎很重要,并且脚本不是由 mod_perl 处理的。然而,在 apache 2.4 中,排序似乎并不重要,脚本现在由 mod_perl 处理。

出现错误是因为这个脚本不是(也从未打算)由 mod_perl 处理。解决方法是将脚本的 URI 更改为 /somethingelse/script。

感谢大家的评论。

4

1 回答 1

1

根本原因是 mod_perl,再加上 apache 2.2 和 2.4 之间的(可能的)变化。脚本的 apache 配置,给它一个 /cgi-bin/script 的 ScriptAlias URI,发生在设置 URI /cgi-bin 以由 mod_perl 处理之前。在 apache 2.2 中,这种排序似乎很重要,并且脚本不是由 mod_perl 处理的。然而,在 apache 2.4 中,排序似乎并不重要,脚本现在由 mod_perl 处理。

出现错误是因为这个脚本不是(也从未打算)由 mod_perl 处理。解决方法是将脚本的 URI 更改为 /somethingelse/script。– 半开眼

于 2017-08-16T11:37:09.247 回答