Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Attempt to free unreferenced scalar: (or how I learnt to stop worrying and love @INC)

by grinder (Bishop)
on Jan 23, 2004 at 14:24 UTC ( #323565=perlmeditation: print w/replies, xml ) Need Help??

Executive summary: a program that was working, broke, and I fixed it. The trail that led to the resolution of the problem is, IMHO, worth studying.

I upgraded FreeBSD on a server the other day, from 4.9-PRERELEASE to 5.2-RELEASE. I compiled perl 5.8.3 with 100% regression test success and installed it under /usr/local (the default perl continues to live in /usr). This morning I noticed that a script that worked correctly before is now spewing the following error:

Attempt to free unreferenced scalar: SV 0x849856c at /usr/local/lib/perl5/5.8.3/i386-freebsd/IO/ line 137.

I isolated the problem down to the following routine. It's in a child process that is simply checking to see whether something is listening on a remote port:

sub _listening { my $s = IO::Socket::INET->new( Timeout => TIMEOUT, PeerHost => $_[0], Proto => $_[1], PeerPort => $_[2] ) or return 0; close $s; return 1; }

Commenting out the IO::Socket::INET constructor and just returning 1 made the problem go away... So, what to do?

Figuring that my $foo = thing() or return might be considered too unclean these days, I rewrote it as follows:

sub _listening { my $ok = 0; my $s = IO::Socket::INET->new( Timeout => TIMEOUT, PeerHost => $_[0], Proto => $_[1], PeerPort => $_[2] ); if( $s ) { close $s; $ok = 1; } return $ok; }

... the error messages, however, continued. I checked with CPAN, the IO::Socket and IO::Socket::INET modules are up to date (I would have been really surprised if they weren't, but it was a cheap test). I had a look at the module. The reported line is in the connect routine, at the line

$sock->blocking(1) if $blocking;

I starting searching on the web, but came up with nothing at all (which is part of the reason why I decided to write this down, maybe it will help someone on the future). After that, I started to try and hunt down where the sub blocking was defined. At that point things started to resemble a maze of twisty passages, all alike. Following the use and require statements became a wild goose chase. For /usr/local/bin/perl, @INC contains:

/usr/local/lib/perl5/5.8.3/i386-freebsd /usr/local/lib/perl5/5.8.3 /usr/local/lib/perl5/site_perl/5.8.3/i386-freebsd /usr/local/lib/perl5/site_perl/5.8.3 /usr/local/lib/perl5/site_perl/5.8.0/i386-freebsd /usr/local/lib/perl5/site_perl/5.8.0 /usr/local/lib/perl5/site_perl/5.6.1 /usr/local/lib/perl5/site_perl/5.005 /usr/local/lib/perl5/site_perl

That's an awfully long list. I started to wonder if I didn't have a problem with inter-version mismatches. To test this out, I added the following to the top of my script:

BEGIN { @INC = (qw( /usr/local/lib/perl5/5.8.3/i386-freebsd /usr/local/lib/perl5/5.8.3 /usr/local/lib/perl5/site_perl/5.8.3/i386-freebsd /usr/local/lib/perl5/site_perl/5.8.3 /usr/local/lib/perl5/site_perl . )); }

Things fell apart immediately at this point, because perl could no longer find the other modules that the program required. So I fired up a CPAN shell, and installed things as required. And at the end of it all... no more error messages. What is more, now that the modules are installed for 5.8.3, I can remove the @INC kluge and the program works without squawking.

In an ideal world, I should see what I've installed on this machine for 5.005_03, 5.6.1 and 5.8.0 and reinstall them explicitly for 5.8.3 and delete the old directories once and for all (notwithstanding the libraries for the perl that is bundled with the OS, of course).

So that's that, may this help someone some day...

Replies are listed 'Best First'.
Re: Attempt to free unreferenced scalar: (or how I learnt to stop worrying and love @INC)
by Abigail-II (Bishop) on Jan 23, 2004 at 14:45 UTC
    This may very well be a bug. Either in Perl, or in some module. Your @INC suggests that binary modules are picked from either the 5.8.3 core libs, or from either the 5.8.3 or 5.8.0 site libs. Since 5.8.3 is supposed to be binary compatible with 5.8.0, this should be OK.

    So, either 5.8.3 isn't binary compatible, or there's a module somewhere that has a binary compatibality issue, but installed itself in a non-binary directory.

    Too bad you didn't figure out which module was causing the problem.


      Hmm, I didn't consider it was a bug in Perl, I assumed it was my fault. Also, it's the first time I've come across such a problem, so I wasn't sure of the steps to take. I'll know better next time.

      I actually thought I would have to live with the @INC hack until such time as I could clean up my installation. By chance I deleted the BEGIN block and noticed that it worked anyway.

      For what it's worth, this is the list of modules I reinstalled (in order of appearance):

      • DBI
      • DBD::Pg
      • NetAddr::IP
      • Parallel::ForkManager

      I think the problem module is Parallel::ForkManager. CPAN reported it as being up to date, and yet the program continued to emit "Attempt to free" messages. I did a force install and the problem cleared up after that.

      But then P::FM appears to be a pure Perl module. Only DBI and DBD::Pg contain XS code (which is what I would expect to cause the problem), and, apart from action-at-a-distance, I don't see what they have to do with the problem of the IO::Socket::INET constructor. Still, stranger things have happened.

      Perhaps the modules that were installed for 5.8.3 were not installed for 5.8.0. If that is the case then it is not a bug. His @INC included 5.6.1 and 5.005 and those are definitely not binary compatible with 5.8.x.

        His @INC included 5.6.1 and 5.005 and those are definitely not binary compatible with 5.8.x.

        ...but his @INC did not include the arch dirs for 5.6.1 & 5.005. I've had this problem as well, in fact I posted it to the dbi-users list. Nothing was resolved. I've had this happen on FreeBSD, OSF and Linux. I was upgrading the Perl on these servers to 5.8.1. I have a CPAN script that installs the modules we use and it would "hang" when installing Bundle::DBI. On the OSF it actually used all the swap space up. I finally was able to resolve this by moving the */site_perl/5.6.1 to a temp name and installed all the modules in the 5.8.1 tree. Everything I've read indicates that 5.8.x is supposed to only look for the Perl only modules and not use the old XS compiled modules. Maybe there is a XS compiled module in a non-standard dir. The only way I've been able to upgrade is to rename the site_perl/5.6.1 dir. I'm glad someone else has had this problem, I thought I was the only one. I have another server that needs to be upgraded, so I am going to install everything manually and see if can figure out why this is happening.


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://323565]
Approved by broquaint
Front-paged by broquaint
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2018-06-22 02:54 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (121 votes). Check out past polls.