gpt4 book ai didi

perl - binmode + mod_perl 2.0.5 + Parse::RecDescent = 段错误

转载 作者:行者123 更新时间:2023-12-04 12:41:29 24 4
gpt4 key购买 nike

重要更新:问题与 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 (ERROR, ">&STDERR"); 执行由 Parse::RecDescent 提供。

原问题:

我在 mod_perl 2.0.5 下的 Spreadsheet::WriteExcel 有问题
Apache 因段错误而死,我发现它发生在 require Parse::RecDescent内声明 Spreadsheet::WriteExcel包裹。

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::RecDescent的代码并注意到类似 open (ERROR, ">&STDERR"); 的声明

好吧,经过一些额外的实验,我有了这个简约的 Plack 应用程序来重现段错误:
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 没有段错误。

如果我两者都做,它就会出现段错误。

作为一种解决方法,我可以避免使用 binmode在 STDERR 上,但效果不佳。

关于在哪里以及如何解决这个问题的任何建议?

谢谢。

我的环境:
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

更新:相同的代码在过时的 Ubuntu 8.04 + perl 5.8.8 + mod_perl2 2.0.3 下运行良好

Upd2:FreeBSD 9.1 + perl 5.14 + mod_perl 2.0.8 -- 段错误重复
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 也能工作设置,那么也许你有一个解决方案(如果不是为什么会发生这种情况的真正答案)。比照此摘录自 perldoc -f binmode :

On some systems (in general, DOS- and Windows-based systems) binmode() is 
necessary when you're not working with a text file. For the sake of portability
it is a good idea always to use it when appropriate, and never to use it when it
isn't appropriate. Also, people can set their I/O to be by default UTF8-encoded
Unicode, not bytes.

In other words: regardless of platform, use binmode() on binary data, like
images, for example. ...

perldoc的独特风格中我认为这可能暗示您可以设置 binmode对于某些文件句柄/套接字,而不是为其他文件句柄/套接字进行调整,直到“错误”(如果是一个)不出现。

编辑 :

由于您的简单且可重现的错误/测试用例,我认为这将得到解决。我构建了 perl 的调试版本尝试跟踪错误,它在 liberperl.so 中- 某处 PerlIOBase_dup() .我也在 IRC 上向知道的人提到了这一点,他们得出结论,这是一个真实的(即可报告的) perl漏洞。

这是我的运行方式 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 - binmode + mod_perl 2.0.5 + Parse::RecDescent = 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18533538/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com