http://www.perlmonks.org?node_id=893139

ELISHEVA has asked for the wisdom of the Perl Monks concerning the following question:

Today while testing code I ran across an error that was new to me: "Attempt to free unreferenced scalar: SV 0x8238030, Perl interpreter: 0x817b008 during global destruction.". I've been able to isolate the issue to the code at the end of this post.

It seems to be due to some interaction between tied handles, select, temporary file handles created by File::Temp, and number of lines of code in the module(!). Merely by commenting out one line of code in a method that is never even called, I can make Perl stop complaining for 2 of the 3 complaining cases.

I'm guessing this is a Perl bug because commenting out a line that is never executed shouldn't change the behavior of a script, but I'd like another set of eyes. Is this just on my build/platform: Debian (Lenny) - system perl (5.10.0)? Am I using something in a way that was never intended and so confusing perl?

As can be seen from the script below, I've tried a number of different types of file handles (string backed, plain, STDOUT, STDERR, permanent temp files) and the only kind of handle that consistently shows a problem is a runtime only temp file: i.e. a nameless temp file handle or a named file handle that is supposed to go away when the program dies.

Also I'm curious what is the Perl interpreter doing that it is so sensitive to a line commented out? Memory corruption? Something else?

The test script I'm using is posted below.

use strict; use warnings; use File::Temp; use Symbol; { package MyWrapper; # VERY STRANGE - although this method is never called, if one # comments one or more lines below complains stop sub xxx { my $x=1; #comment this out:'temp', 'temp_keep' stop complaining my $y=2; my $z=3; } sub TIEHANDLE { my ($sClass, $self, $fh) = @_; $self = bless($self, $sClass); ${*$self}{io_window_fh} = $fh; return $self; } sub PRINT { my $self = shift; my $fh = ${*$self}{io_window_fh}; CORE::print $fh "@_"; } sub DESTROY { print STDERR "$_[0]: I'm dying...dead\n"; } } #--------------------------------------------------------------- # Select File Handle for test #--------------------------------------------------------------- # These complain: attempt to free unreferenced scalar # during global destruction my $fh; if (!$ARGV[0] || ($ARGV[0] eq 'temp')) { $fh = File::Temp::tempfile( UNLINK => 1); } elsif ($ARGV[0] eq 'temp_keep') { # This also complains $fh = File::Temp::tempfile( UNLINK => 0); } elsif ($ARGV[0] eq 'temp_unlink_name') { ($fh, my $name) = File::Temp::tempfile( UNLINK => 1); # BUT ALL THESE ARE OK } elsif ($ARGV[0] eq 'temp_keep_name') { ($fh, my $name) = File::Temp::tempfile( UNLINK => 0); } elsif ($ARGV[0] eq 'buf') { # no complaints with this file handle my $sBuf=''; open $fh, '+>', \$sBuf; } elsif ($ARGV[0] eq 'stdout') { # nor with this one $fh = \*STDOUT; } elsif ($ARGV[0] eq 'stderr') { # nor with this one $fh = \*STDERR; } else { # nor with this one open ($fh, '>', $ARGV[0]); } #--------------------------------------------------------------- # Demonstrate bug #--------------------------------------------------------------- my $fhWrapper = Symbol::gensym; tie(*$fhWrapper, 'MyWrapper', $fhWrapper, $fh); select $fhWrapper; print "Hello World\n"; print STDOUT "Done\n"; END { print STDERR "Global destruction beginning\n"; }

Replies are listed 'Best First'.
Re: Temp file handles refcount bug?
by ikegami (Patriarch) on Mar 14, 2011 at 20:39 UTC

    I get the error on 5.12.2 and 5.12.3. Didn't checking blead. The scalar in question is this one

    $fh = IV(0x933914c) at 0x9339150 REFCNT = 1 FLAGS = (PADMY,ROK) RV = 0x938abe8 SV = PVGV(0x9361de8) at 0x938abe8 <-------- REFCNT = 3 FLAGS = () NAME = "$fh" NAMELEN = 3 GvSTASH = 0x924ce18 "File::Temp" GP = 0x923d880 SV = 0x0 REFCNT = 1 IO = 0x922ae48 FORM = 0x0 AV = 0x0 HV = 0x0 CV = 0x0 CVGEN = 0x0 LINE = 513 FILE = "/home/eric/usr/perlbrew/perls/perl-5.12.2/lib/5.12.2/Fil +e/Temp.pm" FLAGS = 0x0 EGV = 0x938abe8 "$fh"

    Destroying the tied handle before global destruction appears to avoid the problem.

    { my $fhWrapper = Symbol::gensym; tie(local *$fhWrapper, 'MyWrapper', $fhWrapper, $fh); ... }

      That doesn't work on my machine, but deselecting the tied handle does silence the complaint, e.g. making the last line select STDOUT or some such.

Re: Temp file handles refcount bug?
by dave_the_m (Monsignor) on Mar 14, 2011 at 22:33 UTC
    This was fixed (by me :-) in 5.13.6 by commit

    57ef47cc7bcd1b57927d5010f363ccaa10f1d990

    Dave.

Re: Temp file handles refcount bug?
by Eliya (Vicar) on Mar 14, 2011 at 20:52 UTC

    Just for the record, I can reproduce the problem with Perl 5.12.2 on Linux (Ubuntu) for all of the cases except the last three (i.e., in contrast to you, also for 'temp_keep_name' and 'buf').  With 5.10.1, however, I get the error only with case 'buf'.

    (Destroying the tied handle before global destruction (as mentioned by ikegami) makes no difference.)

Re: Temp file handles refcount bug?
by GrandFather (Saint) on Mar 14, 2011 at 20:17 UTC

    It seems to run correctly for me using 5.10.1 on Windows. There were some important bug fixes between .0 and .1 so it would be worth upgrading at last that much if possible, or at least install a 5.10.1 in a sandbox and see if that has fixed the problem.

    True laziness is hard work
Re: Temp file handles refcount bug?
by fidesachates (Monk) on Mar 14, 2011 at 20:41 UTC
    I can't help you shed any light on the matter, but since Grandfather states the program runs correctly for him, I thought I'd just mention that I run into the bug Eli sees.

    test1.pl >/dev/null Global destruction beginning MyWrapper=GLOB(0x7408e0): I'm dying...dead Attempt to free unreferenced scalar: SV 0x835160, Perl interpreter: 0x +549ec0 during global destruction. uname -a SunOS nygeqdbxptuat2 5.10 Generic_142901-12 i86pc i386 i86pc perl -v This is perl, v5.8.8 built for i86pc-solaris-thread-multi-64 Copyright 1987-2006, Larry Wall Perl may be copied only under the terms of either the Artistic License + or the GNU General Public License, which may be found in the Perl 5 source ki +t. Complete documentation for Perl, including FAQ lists, should be found +on this system using "man perl" or "perldoc perl". If you have access to + the Internet, point your browser at http://www.perl.org/, the Perl Home Pa +ge. perlmodver File::Temp File::Temp : 0.16 perlmodver Symbol Symbol : 1.06
Re: Temp file handles refcount bug?
by CountZero (Bishop) on Mar 14, 2011 at 22:45 UTC
    I cannot reproduce this error on Strawberry Perl 5.12.1 (perl 5, version 12, subversion 1 (v5.12.1) built for MSWin32-x86-multi-thread) on Windows XP.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James