Binmode + mod_perl 2.0.5 + Parse :: RecDescent = segmentaion fault

Important update: the problem is not related to Apache or mod_perl. The simplest demonstration:

> perl -le 'use PerlIO::via::QuotedPrint; binmode(\*STDERR, ":via(PerlIO::via::QuotedPrint):utf8"); open (ERROR, ">&STDERR");' zsh: segmentation fault perl -le 

In fact, binmode is executed by my code and open (ERROR, ">&STDERR"); using Parse :: RecDescent.


The original question:

I have a problem with Spreadsheet :: WriteExcel in mod_perl 2.0.5 Apache dies with a segmentation error, and I found out that it occurs in require Parse::RecDescent as part of the Spreadsheet::WriteExcel .

strace shows that the last things that happen duplicate 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) --- 

I read the Parse::RecDescent and noticed expressions such as open (ERROR, ">&STDERR");

Ok, after some extra experimentation, I have this minimalistic Plack application for playing 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; 

(I actually use a binmode layer different from PerlIO::via::QuotedPrint , but the effect is the same)

If I do not execute binmode(\*STDERR, ":via(PerlIO... , apache is not segfault.

Unless I duplicate STDERR , apache is not segfault.

If I do both, it will be segfaults.

As a workaround, I can avoid using binmode on STDERR, but this is not good.

Any suggestions on where and how to fix this?

Thanks.

My environment:

 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 

Update: The same code works well with legacy Ubuntu 8.04 + perl 5.8.8 + mod_perl2 2.0.3

Update 2: FreeBSD 9.1 + perl 5.14 + mod_perl 2.0.8 - segfault repetitions

 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 
+7
segmentation-fault perl mod-perl2
source share
1 answer

If it works without the binmode set, then perhaps you have a solution (if not a real answer to the question of why this is happening). cf this excerpt from 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. ... 

In the inimitable style of perldoc I think this may mean that you can set binmode for certain file descriptors / sockets, and not for others, until an "error" (if there is one) appears.

EDIT

Thanks to your simple and reproducible error / test case, I think this will be fixed. I built a debug version of perl to try and track the error, and it is in liberperl.so - somewhere in PerlIOBase_dup() . I also mentioned this in the IRC to people who would know, and they came to the conclusion that this is a real mistake (i.e. Reporting) perl .

This is how I started gdb :

 (gdb) run -Dx -le 'use PerlIO::via::QuotedPrint; binmode(\*STDERR, ":via(PerlIO::via::QuotedPrint):utf8"); open (ERROR, ">&STDERR");' 

and it so happened:

 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; 

Hi, you made perl better!

+3
source share

All Articles