Skip Menu |

This queue is for tickets about the DBM-Deep CPAN distribution.

Report information
The Basics
Id: 77746
Status: resolved
Priority: 0/
Queue: DBM-Deep

People
Owner: Nobody in particular
Requestors: RFREIMUTH [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 1.0015
Fixed in: (no value)



Subject: Cannot delete DBM::Deep file after copying inner key (ref count issue?)
Cross-posted from http://www.perlmonks.org/?node_id=974578... I stumbled across a bug in my code that I tracked down to something I am doing with a DBM::Deep file. When I assign the inner key of a DBM hash-of-hrefs to another variable and then try to delete the file, I get an error when the inner key is a href but not when it is a non-ref scalar. use strict; use warnings; use DBM::Deep; my $db_file = 'href_nocopy'; { my $db = DBM::Deep->new( $db_file ); $db->{key} = {}; } print "\nDeleting $db_file\n"; unlink( $db_file ) || warn $!; # succeeds $db_file = 'href_copy'; { my $db = DBM::Deep->new( $db_file ); $db->{key} = {}; my $db2 = $db->{key}; } print "\nDeleting $db_file\n"; unlink( $db_file ) || warn $!; # fails (permission denied) $db_file = 'nonref_copy'; { my $db = DBM::Deep->new( $db_file ); $db->{key} = 1; my $db2 = $db->{key}; } print "\nDeleting $db_file\n"; unlink( $db_file ) || warn $!; # succeeds Any ideas? I didn't find any documentation about this elsewhere.
On Sun Jun 10 22:22:46 2012, RFREIMUTH wrote: Show quoted text
> $db_file = 'href_copy'; > > { > my $db = DBM::Deep->new( $db_file ); > $db->{key} = {}; > my $db2 = $db->{key}; > } > > print "\nDeleting $db_file\n"; > unlink( $db_file ) || warn $!; # fails (permission denied)
Show quoted text
> Any ideas? I didn't find any documentation about this elsewhere.
That sounds like a circular reference. Those are hard to track down, but I’ll try if I have time.
Subject: Re: [rt.cpan.org #77746] Cannot delete DBM::Deep file after copying inner key (ref count issue?)
Date: Tue, 12 Jun 2012 09:36:37 -0700 (PDT)
To: bug-DBM-Deep [...] rt.cpan.org
From: Robert Freimuth <rrfreimuth2 [...] yahoo.com>
Hi, I'm not sure that it's circular, as  $db never points to $db2 (but it wouldn't surprise me if ref-counting is somehow involved).  I'm just using $db2 as a shortcut into a deeper level of the $db structure. Thanks for taking the time to look into this. Bob --- On Mon, 6/11/12, Father Chrysostomos via RT <bug-DBM-Deep@rt.cpan.org> wrote: From: Father Chrysostomos via RT <bug-DBM-Deep@rt.cpan.org> Subject: [rt.cpan.org #77746] Cannot delete DBM::Deep file after copying inner key (ref count issue?) To: RFREIMUTH@cpan.org Date: Monday, June 11, 2012, 12:56 AM <URL: https://rt.cpan.org/Ticket/Display.html?id=77746 > On Sun Jun 10 22:22:46 2012, RFREIMUTH wrote: Show quoted text
> $db_file = 'href_copy'; > > { >     my $db = DBM::Deep->new( $db_file ); >     $db->{key} = {}; >     my $db2 = $db->{key}; > } > > print "\nDeleting $db_file\n"; > unlink( $db_file ) || warn $!;  # fails (permission denied)
Show quoted text
> Any ideas? I didn't find any documentation about this elsewhere.
That sounds like a circular reference.  Those are hard to track down, but I’ll try if I have time.
On Tue Jun 12 12:36:47 2012, rrfreimuth2@yahoo.com wrote: Show quoted text
> Hi, > > I'm not sure that it's circular, as  $db never points to $db2 (but it > wouldn't surprise me if ref-counting is somehow involved).  I'm just > using $db2 as a shortcut into a deeper level of the $db structure. > > Thanks for taking the time to look into this.
Devel::FindRef to the rescue! Here is a variation of your script, with the output below. Notice that $db2 is still set even after weakening. use strict; use warnings; use DBM::Deep; use Scalar::Util 'weaken'; my $db_file = 'href_nocopy'; { my $db = DBM::Deep->new( $db_file ); $db->{key} = {}; weaken $db; warn $db; } $db_file = 'href_copy'; { my $db = DBM::Deep->new( $db_file ); $db->{key} = {}; my $db2 = $db->{key}; weaken $db; weaken $db2; warn $db; warn $db2; if ($db2) { use Devel::FindRef; print Devel'FindRef'track $db2; } } __END__ Use of uninitialized value $db in warn at - line 14. Warning: something's wrong at - line 14. Use of uninitialized value $db in warn at - line 26. Warning: something's wrong at - line 26. DBM::Deep::Hash=HASH(0x33d9f0) at - line 27. DBM::Deep::Hash=HASH(0x33d9f0) [refcount 3] is +- referenced by REF(0x8515f0) [refcount 1], which is | a temporary on the stack. +- referenced by REF(0x8038d0) [refcount 1], which is the member '0' of HASH(0x881f80) [refcount 1], which is referenced by REF(0x8517c0) [refcount 1], which is the member '609' of HASH(0x88c160) [refcount 1], which is referenced by REF(0x88c150) [refcount 1], which is the member 'cache' of DBM::Deep::Engine::File=HASH(0x87dec0) [refcount 1], which is referenced by REF(0x88c1b0) [refcount 1], which is the member 'engine' of DBM::Deep::Hash=HASH(0x88c0f0) [refcount 2], which is referenced by REF(0x88c1e0) [refcount 1], which is referenced (in mg_obj) by 'P' type magic attached to DBM::Deep::Hash=HASH(0x33d9f0) [refcount 3], which is not referenced within the search depth. I don’t have time to write tests for it right now, but I believe the attached patch will fix it. Does it work for you? If so, I will put it in the next release, maybe in a couple of days. Show quoted text
> > --- On Mon, 6/11/12, Father Chrysostomos via RT <bug-DBM- > Deep@rt.cpan.org> wrote: > > From: Father Chrysostomos via RT <bug-DBM-Deep@rt.cpan.org> > Subject: [rt.cpan.org #77746] Cannot delete DBM::Deep file after > copying inner key (ref count issue?) > To: RFREIMUTH@cpan.org > Date: Monday, June 11, 2012, 12:56 AM > > <URL: https://rt.cpan.org/Ticket/Display.html?id=77746 > > > On Sun Jun 10 22:22:46 2012, RFREIMUTH wrote:
> > $db_file = 'href_copy'; > > > > { > >     my $db = DBM::Deep->new( $db_file ); > >     $db->{key} = {}; > >     my $db2 = $db->{key}; > > } > > > > print "\nDeleting $db_file\n"; > > unlink( $db_file ) || warn $!;  # fails (permission denied)
>
> > Any ideas? I didn't find any documentation about this elsewhere.
> > That sounds like a circular reference.  Those are hard to track down, > but I’ll try if I have time. >
Subject: open_RSWprf3A.txt
diff --git a/lib/DBM/Deep/Sector/File/Reference.pm b/lib/DBM/Deep/Sector/File/Reference.pm index 9b8cd5d..1e50bab 100644 --- a/lib/DBM/Deep/Sector/File/Reference.pm +++ b/lib/DBM/Deep/Sector/File/Reference.pm @@ -423,9 +423,7 @@ sub data { }); $$cache_entry{ $trans_id } = $obj; - if($engine->{external_refs}) { - Scalar::Util::weaken($$cache_entry{ $trans_id }); - } + Scalar::Util::weaken($$cache_entry{ $trans_id }); } else { $obj = $$cache_entry{ $trans_id };
On Fri Jun 15 11:32:11 2012, SPROUT wrote: Show quoted text
> On Tue Jun 12 12:36:47 2012, rrfreimuth2@yahoo.com wrote:
> > Hi, > > > > I'm not sure that it's circular, as  $db never points to $db2 (but
> it
> > wouldn't surprise me if ref-counting is somehow involved).  I'm just > > using $db2 as a shortcut into a deeper level of the $db structure. > > > > Thanks for taking the time to look into this.
> > Devel::FindRef to the rescue! > > Here is a variation of your script, with the output below. Notice > that $db2 is still set even > after weakening.
I forgot to mention: The circular reference is inside DBM::Deep itself. Since $db{key} == $db{key} must return true for sanity’s sake, the Perl hash that is created when the database hash is read is cached, so the same Perl hash can be returned each time. Since the hash is linked to the database, it references the database engine, in whose cache it resides. So that’s where the circular reference is.
I’ve just uploaded DBM::Deep 2.0008 with a fix for this. See also: https://github.com/robkinyon/dbm-deep/commit/d669a3211
Subject: Re: [rt.cpan.org #77746] Cannot delete DBM::Deep file after copying inner key (ref count issue?)
Date: Fri, 30 Nov 2012 00:05:03 -0800 (PST)
To: bug-DBM-Deep [...] rt.cpan.org
From: Robert Freimuth <rrfreimuth2 [...] yahoo.com>
THANK YOU!! --- On Sun, 6/17/12, Father Chrysostomos via RT <bug-DBM-Deep@rt.cpan.org> wrote: Show quoted text
> From: Father Chrysostomos via RT <bug-DBM-Deep@rt.cpan.org> > Subject: [rt.cpan.org #77746] Cannot delete DBM::Deep file after copying inner key (ref count issue?) > To: RFREIMUTH@cpan.org > Date: Sunday, June 17, 2012, 3:11 PM > <URL: https://rt.cpan.org/Ticket/Display.html?id=77746 > > > I’ve just uploaded DBM::Deep 2.0008 with a fix for this. > > See also: https://github.com/robkinyon/dbm-deep/commit/d669a3211 > >