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

Dignified Monks,

I have a script that works fine under windows and Activeperl 5.10.
It has to be portable to AIX, this is the IBM-Unix derivate, on which the version 5.8.2 is currently running. The script I wrote converts a textfile into another textfile. The script says:
Attempt to free unreferenced scalar: SV 0x302611d0 at ./avp2unit.pl line 7.
Attempt to free unreferenced scalar: SV 0x3027a8ec at ./avp2unit.pl line 8.
Attempt to free unreferenced scalar: SV 0x303c4948 at OutputWriter.pm line 9.
Attempt to free unreferenced scalar: SV 0x303bf310 at OutputWriter.pm line 10.
Attempt to free unreferenced scalar: SV 0x302b7eb4 at ./avp2unit.pl line 9.
And here is my avp2unit.pl-code
#!/usr/bin/perl use v5.8.2; # Use the version which is on the AIX machines use strict; use bigint; use File::Basename; use lib File::Basename::dirname($0); # find .pm files in script's di +r use FunctionsAPI; #<--- line 7. These are my modules... use DataObject; #<--- line 8 use OutputWriter; #<--- line 9 #main { my $argc = @ARGV; if($argc < 1){ die( drawError("Insufficient Parameters", "One or two paramete +rs are needed.")); } my $inputfilename = $ARGV[0]; open(my $AVPFILE, $inputfilename) or die( drawError("Unable to ope +n file $ARGV[0]", "Unfortunatelly, the file: $ARGV[0] is not readable +.")); my $shortfilename; if($inputfilename =~ m/^(.*)\.avp$/) { $shortfilename = $1; } else { $shortfilename = $inputfilename; } my $data = new DataObject(); print "Proceeding ".$inputfilename." -->\n"; for(my $loop=0; !eof($AVPFILE); $loop++ ) { $data->readFile($AVPFILE); + # continue to read the Test inside the AVP-File my $writer = manufacture OutputWriter( $data->{MNEMONIC} ); + # Ask the factory to produce e.g. a KMF-moduleWriter with th +e mnemonic B92A if( defined($writer) ) + # don't do anything if the mnemonic is not recognizesed by th +e factory { unless( translationIncompatible($data) || globalWarningIsS +et() ) { my $outputfilename = $shortfilename.".".sprintf("%04i" +,$loop).'.src'; # e.g. $inputname = example.avp -> + $shortfilename = example $writer->writeTest($data, $outputfilename); + # produce the outputfile with th +e name example0001.src unlink($outputfilename) if globalWarningIsSet(); + # delete file if there happend s.th +. really evil print "\tsuccessfully written file: ".$outputfilename. +"\n" unless globalWarningIsSet(); # print that everything went fin +e } } $data->clearData(); } close($AVPFILE); };
And that is what a module of me looks like:
#!/usr/bin/perl use v5.8.2; # Use the version which is on the AIX machines use strict; # Declare strict checking on variable names, etc. use bigint; # Be able to handle 64-bit integers. Unfortunatelly + also floats are truncated to integer, but that's ok because we're no +t using any of them! package FunctionsAPI; require Exporter; our @ISA = "Exporter"; # inherit from the Exporter-Class our @EXPORT = qw(drawError drawWarning whiteTrim leadingWhiteTr +im); # our functions to get exported by default our $VERSION = 0.01; # this is the momentary package + version my ($INITMEM, $RESULTMEM) = ( 0, 1 ); my $globalwarning = 0; sub ... and so on...
and the other modules are quite similar. The only difference is that they don't use the exporter... What I've found is the following:
Attempt to free unreferenced scalar:
(W internal) Perl went to decrement the reference count of a scalar to see if it would go to 0, and discovered that it had already gone to 0 earlier, and should have been freed, and in fact, probably was freed. This could indicate that SvREFCNT_dec() was called too many times, or that SvREFCNT_inc() was called too few times, or that the SV was mortalized when it shouldn't have been, or that memory has been corrupted.

Does this mean it's an internal error of AIX/perl?

I thank you very much for your help. Comments on the code are also welcomed...
sincerely mck

Replies are listed 'Best First'.
Re: Warning: Freeing unreferenced scalar
by ig (Vicar) on Aug 19, 2009 at 12:01 UTC

    It's interesting that all three of your modules cause warnings yet strict, bigint and File::Basename don't. I would try to find what it is about your modules that is causing the warning. Maybe a simple test program with a minimal module:

    package Test::Package; 1;

    Then load this from:

    #!/usr/bin/perl use v5.8.2; # Use the version which is on the AIX machines use strict; use bigint; use File::Basename; use lib File::Basename::dirname($0); use Test::Package; use FunctionsAPI;

    With something like a binary search, adding and removing bits of FunctionsAPI.pm to/from Test/Package.pm, it shouldn't take long to find what is causing the warnings.

      That was a great idea. I wonder that I didn't hit on it myself.

      So the problem I found out was:
      on AIX we have an old bigint module. I've read that it is globally tunred on and can't be turned off by no use bigint. But I thought that this doesn't count also for all files which are included.
      So the trick was to put the use bigint behind my "use modules"...

      Thank you so much ig and also all other monks in this glory monastery...

      cu mck
Re: Warning: Freeing unreferenced scalar
by rovf (Priest) on Aug 18, 2009 at 15:05 UTC
    use lib File::Basename::dirname($0);

    What is the function call doing here??? Also I think $0 has no meaning yet when the use statements are compiled.

    -- 
    Ronald Fischer <ynnor@mm.st>
      What is the function call doing here???

      Basically BEGIN{ require lib; lib->import( File::Basename::dirname($0) ); }

      Also I think $0 has no meaning yet when the use statements are compiled.

      It is defined, test it

      BEGIN { warn $0 }; use lib $0; print $_,$/ for @INC; __END__

        Thanks for the explanation, I hadn't expected this! Looks really useful. Sorry that I was not able to help you with your original problem then.

        -- 
        Ronald Fischer <ynnor@mm.st>