Subject: | reference count leak with take_imp_data |
Date: | Wed, 13 Apr 2011 17:49:17 +0100 |
To: | bug-DBI [...] rt.cpan.org |
From: | Dave Mitchell <davem [...] iabyn.com> |
The following script, which is a much stripped down variant of
DBD::Oracle's t/14threads.t:
use threads; # or set PERL_DESTRUCT_LEVEL=2
use DBI;
my $imp;
for (1..10) {
my $c = DBI->connect( "dbi:ExampleP:", '',
'', { dbi_imp_data => $imp })
or die;
$imp = $c->take_imp_data;
}
will generate an HV (with backref data), and with a reference count 10
higher than accounted for by anything that points to it.
Between perl 5.13.4 and 5.13.11, this causes the following error:
panic: magic_killbackrefs (flags=ff) during global destruction.
That's now been fixed in bleedperl, but I thought I should report the
underlying issue to you on the grounds that it feels like a bug in
DBI.
If you run the above code under gdb, and set a breakpoint on
Perl_sv_clean_all,
you'll see that it calls Perl_sv_clean_all 10 times. The action of this
function, which is is perl's last-ditch claen-all function, is to, for
every remaining SV, brute-force reduce its reference count by 1.
The fact that Perl_sv_clean_all gets called 10 times is unusual, and
indicates that its refcount is 10 higher than it should be.
If after the second Perl_sv_clean_all, you set a breakpoint on
Perl_sv_clear, then that will catch the bad HV that is finally being freed.
I'm assuming this is the same HV corresponding to the orv arg in
dbih_setup_handle, but after that I'm lost.
--
Any [programming] language that doesn't occasionally surprise the
novice will pay for it by continually surprising the expert.
-- Larry Wall