Front page | perl.perl5.porters |
Postings from December 2004
Re: [perl #32967] [PATCH] Re: More B bugs: svref_2object
Thread Previous
|
Thread Next
From:
Alexey Tourbin
Date:
December 28, 2004 16:54
Subject:
Re: [perl #32967] [PATCH] Re: More B bugs: svref_2object
Message ID:
20041229005337.GE7824@solemn.turbinal.org
On Tue, Dec 28, 2004 at 04:01:49PM -0800, Stephen McCamant wrote:
> AT> Recently I reported this bug on perl5-porters mailing list.
> AT> As there seems to be no immediate interest to this bug,
> AT> I file it for future revision. I assign severity=medium
> AT> because reference counting mechanism seems to be affected.
>
> AT> Brief description: consequent svref_2object calls produce wrong
> AT> B objects in certain cases. Detailed explanation and test cases
> AT> are available via the following links:
>
> AT> http://www.nntp.perl.org/group/perl.perl5.porters/96593
> AT> http://www.nntp.perl.org/group/perl.perl5.porters/96600
>
> I think your diagnosis is correct. The B module in general, and
> svref_2object in particular, does not increase the reference count of
> the SV and OP objects the B::SV and B::OP proxies point to, so bad
> things happen if the proxy is used after the underlying object is
> freed. (I bet with more experimentation you could get a segfault, for
> instance).
Okay, thanks a lot for this clarification. Unfortunately I don't quite
grok reference counting mechanism in Perl (for now). I just have a code
that has a kludge that apparently fixes the mechanism for perl-5.8.x.
The code is as follows:
[...]
use B qw(svref_2object);
our $perlbug32967 = \$version;
my $v = sv_version(svref_2object(\$version));
# process $v
[...]
use B qw(class);
sub sv_version ($) {
my $sv = shift;
my $class = class($sv);
if ($class eq "IV" or $class eq "PVIV") {
return $sv->int_value;
}
if ($class eq "NV" or $class eq "PVNV") {
return $sv->NV;
}
if ($class eq "PVMG") {
for (my $mg = $sv->MAGIC; $mg; $mg = $mg->MOREMAGIC) {
next if $mg->TYPE ne "V";
my @v = $mg->PTR =~ /(\d+)/g;
return $v[0] + $v[1] / 1000 + $v[2] / 1000 / 1000;
}
}
if ($sv->can("PV")) {
my $v = $sv->PV;
if ($v =~ /^\s*\.?\d/) {
$v =~ s/_//g;
return $v + 0;
}
}
return undef;
}
__END__
You see, without referencing $version to global $perlbug32967 variable,
I get a very wrong result (wrong SV object), as of perl-5.8.6. And this
kludge has *no effect* on perl-5.6.1.
So I feel like there's still a subtle problem: I can't understand why
$version and/or svref_2object(\$version) is freed upon subsequent
sv_version() calls. (Well, I only want to know how to fix my code.)
To examine the real code, you may want to take a look at
http://search.cpan.org/dist/rpm-build-perl/ (only PVMG version strings
seems to break things). My original post has a very simple example, though.
> However, I think the best solution is "don't do that, then". B is
> intended for looking at the parse tree, which isn't generally in
> danger of going away, rather than for examining transient values. It
> wouldn't be out of the question to change B so that it always
> SvREFCNT_inc'd the SVs it wrapped, but it would be a fairly major
> change, with some tricky aspects (for instance, should it try to hide
> the increased count from the B::SV:REFCNT method?). Trying to
> reference count OPs would be harder, since most of them don't actually
> store a reference count.
>
> The appended documentation patch attempts to explain that one
> shouldn't do what you tried to do.
>
> -- Stephen
Thread Previous
|
Thread Next