develooper Front page | perl.perl5.porters | Postings from August 2011

[perl #98092] "Attempt to free unreferenced scalar" from dist/threads-shared/t/clone.t

Thread Previous | Thread Next
From:
Father Chrysostomos via RT
Date:
August 31, 2011 09:34
Subject:
[perl #98092] "Attempt to free unreferenced scalar" from dist/threads-shared/t/clone.t
Message ID:
rt-3.6.HEAD-31297-1314808445-606.98092-15-0@perl.org
On Wed Aug 31 09:16:37 2011, sprout wrote:
> On Tue Aug 30 09:46:32 2011, nicholas wrote:
> > $ ./perl -Ilib dist/threads-shared/t/clone.t
> > 1..34
> > ok 1 - Loaded
> > ok 2 - number
> > ok 3 - string
> > ok 4 - 1 arg
> > ok 5 - cloned string
> > ok 6 - cloned scalar ref
> > ok 7 - cloned scalar ref in thread
> > ok 8 - Circular ref typ
> > ok 9 - Circular ref
> > ok 10 - Circular ref in thread
> > Attempt to free unreferenced scalar: SV 0x91eeb0, Perl interpreter:
> >    0x973840 at dist/threads-shared/t/clone.t line 86.
> > Attempt to free unreferenced scalar: SV 0x91eec8, Perl interpreter:
> >    0x973840 at dist/threads-shared/t/clone.t line 86.
> > Attempt to free unreferenced scalar: SV 0x8d15b8, Perl interpreter:
> >    0x973840 at dist/threads-shared/t/clone.t line 86.
> > ok 11 - Cloned circular refs from thread
> > ok 12 - Cloned array
> > ok 13 - Clone mod
> > ok 14 - Original array
> > ok 15 - Clone mod in thread
> > Attempt to free unreferenced scalar: SV 0x902d18, Perl interpreter:
> >    0x74ce60 at dist/threads-shared/t/clone.t line 108.
> > Attempt to free unreferenced scalar: SV 0x902d30, Perl interpreter:
> >    0x74ce60 at dist/threads-shared/t/clone.t line 108.
> > Attempt to free unreferenced scalar: SV 0x977fd8, Perl interpreter:
> >    0x74ce60 at dist/threads-shared/t/clone.t line 108.
> > ok 16 - Clone mod from thread
> > 
> > [etc, no more warnings]
> > 
> > The test case resists most attempts to simplify it - removing
> >    seemingly
> > unrelated earlier blocks from the test case removes the warning.
> 
> I’ve reduced it to this:
> 
> use threads;
> use threads::shared;
> 
> use Devel::Peek;
> Dump *DB::args;
> 
> {
>     my %hsh = ('' => undef);
>     eval {
>         shared_clone(%hsh);
>     };
> }
> 
> my $bar :shared = shared_clone($x);
> 
> #{
>     my $foo :shared;
>     $foo = shared_clone(\$foo);
>     threads->create(sub {
> Dump *DB::args;
>        undef $foo
>     })->join();
> 
>  #}
> __END__
> 
> Those Dump statements I’m using for debugging.
> 
> So far I’ve ascertained that:
> 1) The first unreferenced scalar is an entry in @DB::args that has
> already been used as an AV by the time the thread is started.
> 2) It gets cloned by sv_dup (not _inc) when the thread starts, so it
> ends up in param->unreferenced, and hence on the temps stack in the
thread.
> 3) When the thread exits, cv_undef ends up freeing it, because it is
> somehow reused as a padlist, even though it’s on the temps stack still
> with a refcount of one. I don’t know which cv it is.
> 4) When the temps are freed, we get ‘Attempt to freed unreferenced
scalar’.
> 
> Any ideas where to look now?
> 

Aha!

In pad.c:Perl_padlist_dup:

	/* look for it in the table first.
	   I *think* that it shouldn't be possible to find it there.
	   Well, except for how Perl_sv_compile_2op() "works" :-(   */
	dstpad = (AV*)ptr_table_fetch(PL_ptr_table, srcpad);

	if (dstpad)
	    return dstpad;

No SvREFCNT_inc!

commit 6de654a5795b6f7915432ff16bcdac0688492a9b
Author: Nicholas Clark <nick@ccl4.org>
Date:   Thu Feb 25 14:21:18 2010 +0000

    In Perl_padlist_dup() don't duplicate @_ or pads caused by recursion.
    
    CvDEPTH() is 0 in a new thread, so duplicating pads beyond the
always-present
    first level is a waste of effort and memory.

Adding SvREFCNT_inc makes one warning go away.


Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About