Subject: | substr lvalue held on scratchpad (affecting DBI) |
Date: | Fri, 24 Jul 2009 06:25:14 +1000 |
To: | bug-Test-Weaken [...] rt.cpan.org |
From: | Kevin Ryde <user42 [...] zip.com.au> |
With Test::Weaken 3.001_000 and recent i386 debian perl 5.10.0 the
program below reports a leak
$VAR1 = bless( {
'unfreed_probes' => [
\'Hello There'
],
'weak_probe_count' => 0,
'test' => 1,
'constructor' => sub { "DUMMY" },
'strong_probe_count' => 2,
'probe_count' => 2
}, 'Test::Weaken' );
Some poking around suggests it's a real leak, that the use of lvalue
substr() on a lexical in a function somehow keeps that scalar alive in
the function's scratchpad until the next call to that function.
Assuming this is not a bug in perl it'd be worth a note in the tips and
techniques section of the Test::Weaken docs. Perhaps with suggestions
for calling again through offending functions to reset the scratch, or
whatever.
Alternately in the future maybe some strategic code in Test::Weaken
could help detect a scratchpad scalar (from its flags) and tolerate one
leftover reference on it.
I struck this in recent DBI 1.609 where its _new_dbh() and _new_sth()
functions do such an lvalue substr assignment. Test::Weaken 3.001
applied to a dbh or sth object reports string scalars "DBI::SQLite::db"
and "DBI::SQLite::st" as unfreed.
This only arises with Test::Weaken 3.001 since only it descends into tie
objects, which is where these bits are held in DBI. I believe the
problem is nothing to do with ties though (as the program below shows),
merely that new descending has reached something that was always dodgy!
use strict;
use warnings;
use Test::Weaken;
my $leaks = Test::Weaken::leaks
(sub {
my $str = 'Hello World';
substr($str,-5,5) = 'There';
return \$str;
});
if (! $leaks) {
print "no leaks\n";
} else {
require Data::Dumper;
print Data::Dumper::Dumper($leaks);
}