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

mod-perl2, perl, segmentation-fault

Solution

If it works without `binmode` set, then perhaps you have a solution (if not a real answer to why this is happening). c.f. this extract 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 that might be suggesting you could set `binmode` for certain filehandles/sockets and not for others adjusting until the "bug" (if it is one) does not appear.

EDIT:

Thanks to your simple and reproducible error / test case I think this will get fixed. I built a debug version of `perl` to try tracing the error and it is in `liberperl.so` - somewhere in `PerlIOBase_dup()`. I also mentioned this on IRC to people who would know, and they concluded this is a real (i.e reportable) `perl` bug.

Here's how I ran `gdb`:

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

and this was how things ended up:

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;

Cheers, you made `perl` better!

Problem

Important update: the problem is nothing to do with Apache or mod_perl. The easiest 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 performed by my code and `open (ERROR, ">&STDERR");` by Parse::RecDescent. Original question: I have a problem with Spreadsheet::WriteExcel under mod_perl 2.0.5 Apache dies with segmentation fault, and I found out that it occurs on `require Parse::RecDescent` statement within `Spreadsheet::WriteExcel` package. strace shows that last things that happens is dup'ing 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 through the code of `Parse::RecDescent` and noticed statements like `open (ERROR, ">&STDERR");` Well, after some additional experiments I have this minimalistic Plack app to reproduce the 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; ``` (In fact I use binmode layer other than `PerlIO::via::QuotedPrint`, but effect is the same) If I don't perform `binmode(\*STDERR, ":via(PerlIO...`, apache doesn't segfault. If I don't duplicate `STDERR`, apache doesn't segfault. If I do the both, it segfaults. As a workaround I can avoid using `binmode` on STDERR, but it's not good. Any suggestions on where and how should be fixed 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 ``` Upd: the same code works well under outdated Ubuntu 8.04 + perl 5.8.8 + mod_perl2 2.0.3 Upd2: FreeBSD 9.1 + perl 5.14 + mod_perl 2.0.8 -- segfault repeats ``` 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 ```

Original source