develooper Front page | perl.perl5.porters | Postings from November 2003

Re: problems with Scalar::Util::weaken() and CLONE

Thread Previous | Thread Next
From:
Stas Bekman
Date:
November 27, 2003 17:02
Subject:
Re: problems with Scalar::Util::weaken() and CLONE
Message ID:
3FC69F7C.8060007@stason.org
Back to the fight with Scalar::Util::weaken() and
     Attempt to free unreferenced scalar SV 0xdeadbeaf...
that it causes with ithreads. As Liz has mentioned the problem doesn't exist 
with 5.8.0 w/ithreads, but emerged since 5.8.1.

Does this look like a valid datastructure dump? Here is the code that 
generates it:

#--------------
use Scalar::Util;
use Devel::Peek;

my $data = "a";
my $self = bless \$data, __PACKAGE__;
my $copy = $self;
Scalar::Util::weaken($copy);
Dump $self;
#--------------

Notice the circular reference SV = PVMG(0x8073758) at 0x804c01c, and a ref 
count of 2. Is it possible that this is the cause of the problem? Or is it 
just the way Devel::Peek renders the data?

SV = RV(0x809d508) at 0x804c004
   REFCNT = 1
   FLAGS = (PADBUSY,PADMY,ROK)
   RV = 0x804c01c
   SV = PVMG(0x8073758) at 0x804c01c
     REFCNT = 2
     FLAGS = (PADBUSY,PADMY,OBJECT,RMG,POK,pPOK)
     IV = 0
     NV = 0
     PV = 0x805e1e8 "a"\0
     CUR = 1
     LEN = 2
     MAGIC = 0x8066a38
       MG_VIRTUAL = &PL_vtbl_backref
       MG_TYPE = PERL_MAGIC_backref(<)
       MG_FLAGS = 0x02
         REFCOUNTED
       MG_OBJ = 0x804bf50
       SV = PVAV(0x804d38c) at 0x804bf50
         REFCNT = 2
         FLAGS = ()
         IV = 0
         NV = 0
         ARRAY = 0x805e4c0
         FILL = 0
         MAX = 3
         ARYLEN = 0x0
         FLAGS = (REAL)
         Elt No. 0
         SV = RV(0x809d4f8) at 0x8064c10
           REFCNT = 1
           FLAGS = (PADBUSY,PADMY,ROK,WEAKREF,IsUV)
           RV = 0x804c01c
           SV = PVMG(0x8073758) at 0x804c01c
             REFCNT = 2
             FLAGS = (PADBUSY,PADMY,OBJECT,RMG,POK,pPOK)
             IV = 0
             NV = 0
             PV = 0x805e1e8 "a"\0
             CUR = 1
             LEN = 2
             MAGIC = 0x8066a38
               MG_VIRTUAL = &PL_vtbl_backref
               MG_TYPE = PERL_MAGIC_backref(<)
               MG_FLAGS = 0x02
                 REFCOUNTED
               MG_OBJ = 0x804bf50
               SV = PVAV(0x804d38c) at 0x804bf50
                 REFCNT = 2
                 FLAGS = ()
                 IV = 0
                 NV = 0
                 ARRAY = 0x805e4c0
                 FILL = 0
                 MAX = 3
                 ARYLEN = 0x0
                 FLAGS = (REAL)
             STASH = 0x804be78   "main"
     STASH = 0x804be78   "main"

I've patched sv.c to dump the sv in 'Attempt to free unreferenced scalar SV...

and now the code produces an interesting thing:

#--------------
use Scalar::Util;
use Devel::Peek;

my $data = "a";
my $self = bless \$data, __PACKAGE__;
my $copy = $self;
Scalar::Util::weaken($copy);
#Dump $self;

use threads;
threads->new(sub { print "thread started\n";})->detach for (1..1);
sleep 1;
#--------------

% perl-5.8.3-ithread weaken2
thread started
Attempt to free unreferenced scalar: SV 0x814e2b8.
SV = PV(0x81c26b8) at 0x814e2b8
   REFCNT = 1
   FLAGS = (TEMP,POK,pPOK)
   PV = 0x8183830 "Attempt to free unreferenced scalar: SV 0x814e2b8.\12"\0
   CUR = 51
   LEN = 52

So the unreferenced scalar is the message containing the error message itself? 
Or is it a glitch in do_sv_dump?

Finally the sv.c patch (though it contains original tabs, so it won't apply)

--- sv.c.orig   2003-11-27 15:53:02.000000000 -0800
+++ sv.c        2003-11-27 15:56:28.000000000 -0800
@@ -5328,11 +5328,13 @@
             SvREFCNT(sv) = (~(U32)0)/2;
             return;
         }
-       if (ckWARN_d(WARN_INTERNAL))
+       if (ckWARN_d(WARN_INTERNAL)) {
             Perl_warner(aTHX_ packWARN(WARN_INTERNAL),
                          "Attempt to free unreferenced scalar: SV 0x%"UVxf,
                  PTR2UV(sv));
-       return;
+            do_sv_dump(0, Perl_debug_log, sv, 0, 4, FALSE, 0);
+        }
+        return;
      }
      ATOMIC_DEC_AND_TEST(refcount_is_zero, SvREFCNT(sv));
      if (!refcount_is_zero)

__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


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