Front page | perl.perl5.porters |
Postings from October 2005
[perl #37234] Segfault in PerlIO
From:
Steve Peters via RT
Date:
October 5, 2005 19:26
Subject:
[perl #37234] Segfault in PerlIO
Message ID:
rt-3.0.11-37234-122237.10.0788759381953@perl.org
> [bulb@ucw.cz - Fri Sep 23 10:44:07 2005]:
>
> Hello Again,
>
> I've played with the bug a little more and I include several more scripts,
> that should help pinning down the bug.
>
> First, let's get rid of the dependence on UTF-8 in the mail. This is the
> original testcase, with escape sequence instead of the non-ascii
character.
> Also it now says :encoding(ascii) instead of iso-8859-2.
>
> #!/usr/bin/perl
> use utf8;
> $string = "\x{8336}\n";
> binmode STDERR, ":encoding(ascii)";
> print STDERR $string;
> __END__
>
> Now the next script does NOT crash. It works normally:
>
> #!/usr/bin/perl
> use utf8;
> $SIG{__WARN__} = sub { };
> $string = "\x{8336}\n";
> binmode STDERR, ":encoding(ascii)";
> print STDERR $string;
> __END__
>
> As you can see, the only difference is the line:
>
> $SIG{__WARN__} = sub { };
>
> So it shows, that the problem is caused by printing to STDERR from a
warning
> generated inside print to STDERR. The next script crashes again:
>
> #!/usr/bin/perl
> use utf8;
> $SIG{__WARN__} = sub { print STDERR "BUG\n"; };
> $string = "\x{8336}\n";
> binmode STDERR, ":encoding(ascii)";
> print STDERR $string;
> __END__
>
> Now if the print is not to STDERR, it works. The following script does not
> crash:
>
> #!/usr/bin/perl
> use utf8;
> $SIG{__WARN__} = sub { print "BUG\n"; };
> $string = "\x{8336}\n";
> binmode STDERR, ":encoding(ascii)";
> print STDERR $string;
> __END__
>
> The most surprising is this script though. The next script replaces STDERR
> with STDOUT:
>
> #!/usr/bin/perl
> use utf8;
> $SIG{__WARN__} = sub { print STDOUT "BUG\n"; };
> $string = "\x{8336}\n";
> binmode STDOUT, ":encoding(ascii)";
> print STDOUT $string;
> __END__
>
> Now this script does crash, but in a DIFFERENT WAY. Instead of immediately
> dying of SIGSEGV, it prints the following:
>
> "\x{8336}" does not map to ascii at perlio-bug4.pl line 3.
> \x{8336}
> BUG
> panic: sv_setpvn called with negative strlen at perlio-bug4.pl line 6.
>
> And exits with status 2. Note, that this was on a terminal, where
STDOUT is
> line-buffered (but not unbuffered).
>
The code is essentially going into an infinite loop. The code discovers
the problem with the encoding and when attempting to flush the IO in
ext/PerlIO/encoding/encoding.xs calls Encode::encode(), starting the
cycle all over again. Since Perl_warner() is not capable of handling
anything but char* data, is there a way to turn off encoding while it
warns, then turn it back on? A sort of "no utf-8;" within the core code
itself?
Here's the fatal end of the stack trace.
#0 0x080fc619 in Perl_sv_vcatpvfn (sv=0x933e5d8,
pat=0xb7f6a348 "\"\\x{%04lx}\" does not map to %s", patlen=30,
args=0xbf184324, svargs=0x0, svmax=0, maybe_tainted=0x0) at sv.c:8832
8832 bool has_utf8 = DO_UTF8(sv); /* has the result utf8? */
(gdb) bt
#0 0x080fc619 in Perl_sv_vcatpvfn (sv=0x933e5d8,
pat=0xb7f6a348 "\"\\x{%04lx}\" does not map to %s", patlen=30,
args=0xbf184324, svargs=0x0, svmax=0, maybe_tainted=0x0) at sv.c:8832
#1 0x080fc425 in Perl_sv_vsetpvfn (sv=0x933e5d8,
pat=0xb7f6a348 "\"\\x{%04lx}\" does not map to %s", patlen=30,
args=0xbf184324, svargs=0x0, svmax=0, maybe_tainted=0x0) at sv.c:8754
#2 0x080c7d3e in Perl_vmess (
pat=0xb7f6a348 "\"\\x{%04lx}\" does not map to %s", args=0xbf184324)
at util.c:991
#3 0x080c8c89 in Perl_vwarn (
pat=0xb7f6a348 "\"\\x{%04lx}\" does not map to %s", args=0xbf184324)
at util.c:1260
#4 0x080c943f in Perl_vwarner (err=44,
pat=0xb7f6a348 "\"\\x{%04lx}\" does not map to %s", args=0xbf184324)
at util.c:1377
#5 0x080c9199 in Perl_warner (err=44,
pat=0xb7f6a348 "\"\\x{%04lx}\" does not map to %s") at util.c:1350
#6 0xb7f65537 in encode_method (enc=0xb7c749d8, dir=0xb7c713e0,
src=0x819e0c8, check=2306, offset=0x0, term=0x0, retcode=0x0)
at Encode.xs:162
#7 0xb7f6735b in XS_Encode__XS_encode (cv=0x821f548) at Encode.xs:564
#8 0x080e8bbf in Perl_pp_entersub () at pp_hot.c:2788
#9 0x080c5d55 in Perl_runops_debug () at dump.c:1597
#10 0x08064d6b in S_call_body (myop=0xbf184640, is_eval=0 '\0') at
perl.c:2617
#11 0x080645d7 in Perl_call_sv (sv=0x933e5b8, flags=64) at perl.c:2515
#12 0x0806433a in Perl_call_method (methname=0xb7c7a5b0 "encode", flags=0)
at perl.c:2448
#13 0xb7c78e60 in PerlIOEncode_flush (f=0x81abd24) at encoding.xs:420
#14 0x08164983 in Perl_PerlIO_flush (f=0x81abd24) at perlio.c:1615
#15 0x081678c5 in PerlIOBuf_write (f=0x81abd24, vbuf=0x935ef00, count=61)
at perlio.c:3776
#16 0xb7c79bca in PerlIOEncode_write (f=0x81abd24, vbuf=0x935ef00, count=61)
at encoding.xs:584
#17 0x08164826 in Perl_PerlIO_write (f=0x81abd24, vbuf=0x935ef00, count=61)
at perlio.c:1592
#18 0x080c845c in Perl_write_to_stderr (
message=0x935ef00 "\"\\x{00e8}\" does not map to iso-8859-2 at
rt_37234.pl line 6.\n", msgl en=61) at util.c:1060
#19 0x080c9153 in Perl_vwarn (
pat=0xb7f6a348 "\"\\x{%04lx}\" does not map to %s", args=0xbf184944)
at util.c:1300
#20 0x080c943f in Perl_vwarner (err=44,
pat=0xb7f6a348 "\"\\x{%04lx}\" does not map to %s", args=0xbf184944)
at util.c:1377
-
[perl #37234] Segfault in PerlIO
by Steve Peters via RT