binmode+;mod#u perl 2.0.5+;Parse::RecDescent=分段故障

binmode+;mod#u perl 2.0.5+;Parse::RecDescent=分段故障,perl,segmentation-fault,mod-perl2,Perl,Segmentation Fault,Mod Perl2,重要更新:问题与Apache或mod_perl无关。 最简单的演示: > perl -le 'use PerlIO::via::QuotedPrint; binmode(\*STDERR, ":via(PerlIO::via::QuotedPrint):utf8"); open (ERROR, ">&STDERR");' zsh: segmentation fault perl -le 实际上,binmode是由我的代码执行的,open(错误,“>&STDERR”)按Pa

重要更新:问题与Apache或mod_perl无关。 最简单的演示:

> perl -le 'use PerlIO::via::QuotedPrint; binmode(\*STDERR, ":via(PerlIO::via::QuotedPrint):utf8"); open (ERROR, ">&STDERR");'
zsh: segmentation fault  perl -le
实际上,
binmode
是由我的代码执行的,
open(错误,“>&STDERR”)按Parse::RecDescent


原始问题:

我对mod_perl 2.0.5下的电子表格::WriteExcel有问题 Apache死于分段错误,我发现它发生在
电子表格::WriteExcel
包中的
require Parse::recdence
语句上

strace表明,最后发生的事情是复制STDERR:

[pid 31253] dup(2)                      = 8
[pid 31253] ioctl(8, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffcf66a328) = -1 ENOTTY (Inappropriate ioctl for device)
[pid 31253] lseek(8, 0, SEEK_CUR)       = 0
[pid 31253] --- SIGSEGV (Segmentation fault) @ 0 (0) ---
我通读了
Parse::recdence
的代码,注意到类似
open(ERROR,“>&STDERR”)

在做了一些额外的实验后,我有了这个极简主义的Plack应用程序来重现segfault:

use strict;
use warnings;

# DANGEROUS
use PerlIO::via::QuotedPrint;
binmode(\*STDERR, ":via(PerlIO::via::QuotedPrint):utf8");

my $app = sub {
    my $env = shift;

    open (ERROR, ">&STDERR");  # segmenatation fault

    return [
        '200',
        [ 'Content-Type' => 'text/plain' ],
        [ "hello world" ],
    ];
};

$app;
(事实上,我使用的是binmode层而不是
PerlIO::via::QuotedPrint
,但效果相同)

如果我不执行
binmode(\*STDERR,”:via(PerlIO…
),apache就不会出错

如果我不复制STDERR,apache就不会出错

如果我两者都做,那就错了

作为一种解决方法,我可以避免在STDERR上使用
binmode
,但这并不好

关于在何处以及如何修复此问题,有何建议

谢谢

我的环境:

perl -v |grep version 
This is perl 5, version 14, subversion 2 (v5.14.2) built for x86_64-linux-gnu-thread-multi

uname -a
Linux thinkpad 3.2.0-32-generic #51-Ubuntu SMP Wed Sep 26 21:33:09 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

lsb_release -c
Codename:       precise

dpkg -l |grep mod-perl
ii  libapache2-mod-perl2  2.0.5-5ubuntu1   Integration of perl with the Apache2 web server
Upd:同样的代码在过时的Ubuntu 8.04+perl 5.8.8+mod_perl2.0.3下运行良好

Upd2:FreeBSD9.1+Perl5.14+mod_Perl2.0.8——segfault重复

uname -a                              
FreeBSD liruoko.ru 9.1-RELEASE-p5 FreeBSD 9.1-RELEASE-p5 #7 r253740: Sun Jul 28 16:53:08 MSK 2013     roman@thor.cmc.msu.ru:/usr/obj/usr/src/sys/MINI  amd64

pkg info |grep apache                     
apache22-itk-mpm-2.2.25        Version 2.2.x of Apache web server with itk MPM.

pkg info |grep mod_perl               
ap22-mod_perl2-2.0.8,3         Embeds a Perl interpreter in the Apache2 server

perl -v |grep version
This is perl 5, version 14, subversion 4 (v5.14.4) built for amd64-freebsd

如果它在没有设置
binmode
的情况下工作,那么您可能有了一个解决方案(如果没有真正的答案来解释为什么会发生这种情况)。c.f.以下摘录:

在某些系统(通常是基于DOS和Windows的系统)上,binmode()是
在不使用文本文件时需要。为了便于移植
总是在适当的时候使用它是一个好主意,而永远不要在需要的时候使用它
不合适。此外,用户可以将其I/O设置为默认UTF8编码
Unicode,而不是字节。
换句话说:不管平台如何,对二进制数据使用binmode(),如
例如,图像。。。

在<代码> PrLoc文档>代码>中,我认为这可能意味着您可以为某些文件句柄/套接字设置<代码>二进制模式> /代码>,而不是针对其他人进行调整,直到出现“bug”(如果它是一个)时。

编辑

多亏了您的简单且可重复的错误/测试用例,我认为这将得到修复。我构建了一个调试版本的
perl
来尝试跟踪错误,它位于
liberperl中。因此
-在
PerlIOBase\u dup()
中的某个地方。我还在IRC上向知道的人提到了这一点,他们得出结论,这是一个真实的(即可报告的)错误
perl
bug

下面是我运行gdb的方式:

(gdb) run -Dx -le 'use PerlIO::via::QuotedPrint; binmode(\*STDERR, 
":via(PerlIO::via::QuotedPrint):utf8"); open (ERROR,      ">&STDERR");'
事情就是这样结束的:

Program received signal SIGSEGV, Segmentation fault.
PerlIOBase_dup (f=0x0, o=0x801551060, param=0x0, flags=2) at perlio.c:2307 
2307 PerlIOBase(f)->flags |= PERLIO_F_UTF8;

干杯,你让perl变得更好了!

提供更多信息。操作系统、perl发行版和版本是什么?如果软件过时,升级后会发生什么?Ubuntu 12.04(LTS),perl 5.14,添加到questionRight的详细报告,从那时起perl和mod_perl都发布了几个版本,修复了一些崩溃错误。mod_perl 2.0.8和perl 5.18.1是否仍会发生崩溃?如果是,请参阅BTW,如果我降级(到perl 5.8.8+Ubuntu 8.04),最简单的示例和电子表格::WriteExcel都能很好地工作
设备的不适当ioctl
让我想到了某个套接字或文件的权限。也许您的内核,
apache
mod_perl
perl IO:
层已经改变了它们处理这些的方式。是
apache
mod_从源代码编译的perl