2013-08-30 13 views
7

Ważna aktualizacja: problem nie ma nic wspólnego z Apache ani mod_perl. Najprostszym demonstracji:binmode + mod_perl 2.0.5 + analiza :: RecDescent = błąd segmentacji

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

W rzeczywistości binmode jest wykonywana przez mojego kodu i open (ERROR, ">&STDERR"); przez Parse :: RecDescent.


Oryginalne pytanie:

mam problem z arkusza kalkulacyjnego :: WriteExcel pod mod_perla 2.0.5 Apache umiera z winy segmentacji, i okazało się, że występuje na require Parse::RecDescent rachunku w ciągu Spreadsheet::WriteExcel opakowaniu.

strace pokazuje, że ostatnie rzeczy, które dzieje 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) --- 

czytam przez kodeks Parse::RecDescent i zauważyłem stwierdzenia typu open (ERROR, ">&STDERR");

Cóż, po kilku dodatkowych eksperymentów mam to minimalistyczna Aplikacja Plack do odtworzenia awarii:

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; 

(W rzeczywistości używam warstwy binodowej innej niż PerlIO::via::QuotedPrint, ale efekt jest taki sam)

Jeśli nie wykonam binmode(\*STDERR, ":via(PerlIO..., apache nie ulegnie uszkodzeniu.

Jeśli nie powielę STDERR, apache nie segfault.

Jeśli wykonam obie, to ulegnie uszkodzeniu.

Jako obejście problemu można uniknąć używania binmode na STDERR, ale nie jest to dobre.

Wszelkie sugestie dotyczące tego, gdzie i jak należy to naprawić?

Dzięki.

Moja okolica:

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: ten sam kod działa dobrze pod przestarzałym 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 powtarza

uname -a        
FreeBSD liruoko.ru 9.1-RELEASE-p5 FreeBSD 9.1-RELEASE-p5 #7 r253740: Sun Jul 28 16:53:08 MSK 2013  [email protected]:/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 
+0

Podaj więcej informacji. Jaki jest system operacyjny, dystrybucja i wersja Perla? Jeśli oprogramowanie jest nieaktualne, co się stanie, jeśli dokonasz aktualizacji? – daxim

+0

Ubuntu 12.04 (LTS), perl 5.14, szczegółowy raport został dodany do pytania – Hln

+0

Po prawej, zarówno Perl, jak i mod_perl miały kilka wydań od tego czasu, naprawiając kilka błędów awarii. Czy awaria nadal występuje z mod_perl 2.0.8 i perl 5.18.1? Jeśli tak, zobacz http://perl.apache.org/docs/2.0/devel/debug/c.html#Analyzing_Dumped_Core_Files – daxim

Odpowiedz

3

Jeśli działa bez binmode zestawu, to może masz rozwiązanie (jeśli nie prawdziwą odpowiedź, dlaczego tak się dzieje). c.f. to wyciąg z 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. ... 

W niepowtarzalnym stylu perldocmyślę które mogłyby sugerować można ustawić binmode dla niektórych uchwytów plików/gniazd a nie dla innych dostosowujących do „bug” (jeśli jest jeden) się nie pojawia.

EDIT:

Dzięki swojej prostej i powtarzalnej przypadku błędu/test Myślę, że to będzie się stała. Zrobiłem wersję debugującą perl, aby spróbować śledzić błąd i jest ona w liberperl.so - gdzieś w PerlIOBase_dup(). Wspomniałem o tym również na IRC dla osób, które o tym wiedzą, i doszły do ​​wniosku, że jest to prawdziwy (, tj. zgłoszony) błąd.

Oto jak wpadłem gdb:

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

i to było jak wszystko skończyło się:

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, dokonane perl lepszą!

Powiązane problemy