John Bokma MexIT
freelance Perl programmer

Attempt to free unreferenced scalar

Friday, March 10, 2006 | 0 comments

About one month ago, while working on a huge Perl project I encountered an error similar to the one given below:

Attempt to free unreferenced scalar: SV 0x1cda4e8,
Perl interpreter: 0x22432c
at C:/Perl/lib/Errno.pm line 15.

I was working on a module that used LWP::UserAgent to get a web page. Commenting out the lines I had just added made the error go away, but didn't give a solution. So I uncommented the lines and tested the module, without the other modules I had written, by creating a small test program. The Perl program worked without any problems (which I somehow expected).

Hmm... so where was the culprit. I normally only use a debugger in situations that are very hard, and it looked like this was such an occasion. But before diving into what seemed to going to be a long debugging session, I decided to enter the error message in Google, and see what comes up. In the past this has helped me on many occasions, so I was expecting to find something useful.

I was lucky, since among the search results was a post in the "PERL [sic] Beginners" archive discussing a very similar error message when using WWW::Mechanize and DBI together. Since WWW::Mechanize probably uses LWP::UserAgent under the hood, and I was also using DBI, I had a better idea where to start looking.

And indeed, I was using the DBI selectall_hashref method, which caused somehow to make the get method in LWP::UserAgent to die with "Attempt to free unreferenced scalar ... at C:/Perl/lib/Errno.pm line 15".

Since I already had written a wrapper class for the DBI module I decided to add my own version of the selectall_hashref method, which didn't trigger this odd behavior. I didn't use fetchall_hashref in my this method, since it causes the same issue.

Perl test program showing the problem

Today I finally had some time to write this down, and also write a small test program to show the issue. The Perl script uses the ODBC SQL Server driver, but I could reproduce the problem with MySQL, and guess that it is a DBI issue, not a specific driver issue.

# dbi-lwp-bug.pl
#
# uncommenting any of the "fails" calls results in
#
#   Attempt to free unreferenced scalar: SV 0x1ce90b8,
#   Perl interpreter: 0x224354
#   at C:/Perl/lib/Errno.pm line 15.
#
# $Id: dbi-lwp-bug.pl 1076 2008-09-30 18:08:39Z john $ 

use strict;
use warnings;

use DBI;
use LWP::UserAgent;

use Data::Dumper;

my $dbh = DBI->connect(

    "dbi:ODBC:driver={SQL Server};Server=$ENV{ COMPUTERNAME };",
    '',
    '',
    {
        RaiseError => 1,
        AutoCommit => 1
    }
);

my $query = 'SELECT name FROM dbo.sysdatabases';
my $key_field = 'name';

#selectall_hashref_fails( $dbh, $query, $key_field );
#selectall_hashref_succeeds( $dbh, $query, $key_field );
#fetchall_hashref_fails( $dbh, $query, $key_field );

my $ua = LWP::UserAgent->new();
my $response = $ua->get( 'http://localhost/' );

exit;


sub selectall_hashref_fails {

    my ( $dbh, $query, $key_field ) = @_;

    my $results = $dbh->selectall_hashref( $query, $key_field );

    print Dumper $results;
}


sub fetchall_hashref_fails {

    my ( $dbh, $query, $key_field ) = @_;

    my $sth = $dbh->prepare( $query );
    $sth->execute;

    my $results = $sth->fetchall_hashref( $key_field );

    $sth->finish;

    print Dumper $results;
}


sub selectall_hashref_succeeds {

    my ( $dbh, $query, $key_field ) = @_;

    my $sth = $dbh->prepare( $query );
    $sth->execute();

    my $results;

    while ( my $row = $sth->fetchrow_hashref() ) {

        $results->{ $row->{ $key_field } } = $row;
    }
    $sth->finish;

    print Dumper $results;
}

Uncommenting one of the three functions either gives you the "Attempt to free unreferenced scalar" message ("fails") or works ("succeeds"). The latter can be used as a work-around for selectall_hashref.

Note that commenting out:

my $response = $ua->get( 'http://localhost/' );

line doesn't give the "unreferenced scalar" message with any of the three functions.

Example output of a failure:

$VAR1 = {
          'master' => {
                        'name' => 'master'
                      },
          'model' => {
                       'name' => 'model'
                     },
          'whginc_com' => {
                            'name' => 'whginc_com'
                          },
          'tempdb' => {
                        'name' => 'tempdb'
                      },
          'msdb' => {
                      'name' => 'msdb'
                    }
        };
Attempt to free unreferenced scalar: SV 0x1ce90b8,
Perl interpreter: 0x224354 at C:/Perl/lib/Errno.pm line 15.

Additional information:

perl -v

This is perl, v5.8.7 built for MSWin32-x86-multi-thread
(with 14 registered patches, see perl -V for more detail)

Copyright 1987-2005, Larry Wall

Binary build 815 [211909] provided by ActiveState http://www.ActiveState.com
ActiveState is a division of Sophos.
Built Nov  2 2005 08:44:52

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 kit.

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 Page.

perl -MDBI -e "print $DBI::VERSION"

1.49

Upgrading to DBI version 1.50 using:

ppm upgrade -install http://theoryx5.uwinnipeg.ca/ppms/DBI.ppd

didn't solve the issue. So I reported the issue on CPAN's Request Tracker (RT) using the Public Bug Tracker.

Related

Also today

Please post a comment | read 0 comments | RSS feed