develooper 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





nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About