Front page | perl.perl5.porters |
Postings from January 2010
Re: [perl #65582] 5.10.0 functionality change and segfault
Thread Previous
From:
Dave Mitchell
Date:
January 11, 2010 16:28
Subject:
Re: [perl #65582] 5.10.0 functionality change and segfault
Message ID:
20100112002815.GJ2878@iabyn.com
On Wed, May 13, 2009 at 01:13:12AM -0500, Graham Barr wrote:
>
> On May 13, 2009, at 12:52 AM, Graham Barr wrote:
>
>>
>> On May 12, 2009, at 5:41 PM, Nicholas Clark wrote:
>>
>>> On Tue, May 12, 2009 at 04:24:28PM -0500, Graham Barr wrote:
>>>
>>>> I have not followed closely enough to know if that dropping of magic
>>>> is intentional
>>>
>>> Totally intentional. 24+ bytes used per typeglob (hence per sub or
>>> method)
>>> were used for magic, the sole purpose of which was to deal with
>>> stringifying
>>> the typeglob and assigning strings to it. With several thousand
>>> typeglobs
>>> created by a small program that directly pulls in a moderate number
>>> of
>>> modules, it soon adds up.
>>
>> Sure, OK. As I said I had not been following closely.
>>
>> I have done a little more digging
>>
>> It seems to me that the root of this issue is that
>> in pp_rv2gv where SvTYPE(sv) == SVt_PVIO a call is
>> made to
>>
>> gv_init(gv, 0, "", 0, 0);
>>
>> after this, in blead SvOK(gv) returns true, but in 5.8.9 SvOK(gv) is
>> false
>>
>> this is why defined($y) is true on 5.10.0 but false on 5.8.x and
>> before
>>
>> While not a fix, because lib/Benchmark and op/tie fail, I put in a
>> call to
>> SvOK_off(sv); at the end of that block in 5.10.0 code.
>>
>> The result was that the following matches 5.8.x and before
>>
>> $ ./perl -wle '$x = *STDIN{IO}; $y = *$x; print "$x"; print "$y"'
>> IO::Handle=IO(0x9704eb8)
>> Use of uninitialized value $y in string at -e line 1.
>
> However, the following is still different
>
> $ perl5.8.9 -wle '$x = *STDERR{IO}; $y = *$x; print "$x"; print
> fileno($y); print "$y"'
> IO::Handle=IO(0x84898c4)
> 2
> Use of uninitialized value in string at -e line 1.
>
> $ ./perl -wle '$x = *STDERR{IO}; $y = *$x; print "$x"; print fileno($y);
> print "$y"'
> IO::Handle=IO(0x8168f88)
> Use of uninitialized value $y in print at -e line 1.
>
> Use of uninitialized value $y in string at -e line 1.
>
> So $y was undefined but still valid for use as a filehandle
>
> (time to seep)
> Graham.
I've applied the following commit, which I hope makes for sensible
behaviour:
commit 1809c940bf4737dd262fc0c026e063316c466a28
Author: David Mitchell <davem@iabyn.com>
AuthorDate: Tue Jan 12 00:14:41 2010 +0000
Commit: David Mitchell <davem@iabyn.com>
CommitDate: Tue Jan 12 00:26:59 2010 +0000
fix for [perl #65582] anon globs segfaulting
The following code has had differing behaviours:
my $io_ref = *STDOUT{IO};
my $glob = *$io_ref;
defined($glob) "$glob"
-------------- -------
5.8.8 false "" with uninit warning
5.10.0 true (coredump)
this commit true ""
$glob is essentially an anonymous typeglob (no NAME, EGV or GvSTASH).
It shouldn't register as undefined since it's clearly a valid GV with a
valid IO slot; Stringifying to "" seems to be the right thing, and not
warning seems right too, since its not undef.
Affected files ...
M sv.c
M t/op/gv.t
Differences ...
diff --git a/sv.c b/sv.c
index 063dd19..4e80e18 100644
--- a/sv.c
+++ b/sv.c
@@ -2986,11 +2986,17 @@ Perl_sv_2pv_flags(pTHX_ register SV *const sv, STRLEN *const lp, const I32 flags
gv_efullname3(buffer, gv, "*");
SvFLAGS(gv) |= wasfake;
- assert(SvPOK(buffer));
- if (lp) {
- *lp = SvCUR(buffer);
+ if (SvPOK(buffer)) {
+ if (lp) {
+ *lp = SvCUR(buffer);
+ }
+ return SvPVX(buffer);
+ }
+ else {
+ if (lp)
+ *lp = 0;
+ return (char *)"";
}
- return SvPVX(buffer);
}
if (lp)
diff --git a/t/op/gv.t b/t/op/gv.t
index 1b705ef..72787c4 100644
--- a/t/op/gv.t
+++ b/t/op/gv.t
@@ -12,7 +12,7 @@ BEGIN {
use warnings;
require './test.pl';
-plan( tests => 178 );
+plan( tests => 181 );
# type coersion on assignment
$foo = 'foo';
@@ -560,6 +560,27 @@ foreach my $type (qw(integer number string)) {
"with the correct error message");
}
+# RT #60954 anonymous glob should be defined, and not coredump when
+# stringified. The behaviours are:
+#
+# defined($glob) "$glob"
+# 5.8.8 false "" with uninit warning
+# 5.10.0 true (coredump)
+# 5.12.0 true ""
+
+{
+ my $io_ref = *STDOUT{IO};
+ my $glob = *$io_ref;
+ ok(defined $glob, "RT #60954 anon glob should be defined");
+
+ my $warn = '';
+ local $SIG{__WARN__} = sub { $warn = $_[0] };
+ use warnings;
+ my $str = "$glob";
+ is($warn, '', "RT #60954 anon glob stringification shouln't warn");
+ is($str, '', "RT #60954 anon glob stringification should be empty");
+}
+
__END__
Perl
Rules
--
Red sky at night - gerroff my land!
Red sky at morning - gerroff my land!
-- old farmers' sayings #14
Thread Previous