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"; }