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

I have rather big script (tcp server), and there is one problem with it, from time to time (randomly) the loops are crashing... Lets assume that this loop should execute 100 times, but then i get error (on STDERR) like these lower, and this executed 28 (for ex.) times and finished...
I search through the web and haven't found anything... (just similiar problems without answers)
The question is: Where's the problem, and how to solve it?
Below you hove my script "logs" and corresponding fragment of code.
./us2.pl 257: connection from localhost [ 127.0.0.1 ] at port 1375 at Wed Nov 29 12:24:22 2000 Attempt to free unreferenced scalar at ./us2.pl line 263, <FOL> line 7 +. Attempt to free unreferenced scalar at ./us2.pl line 282. Attempt to free unreferenced scalar at ./us2.pl line 264. Attempt to free unreferenced scalar at ./us2.pl line 282. Attempt to free unreferenced scalar at ./us2.pl line 264. Attempt to free unreferenced scalar at ./us2.pl line 282. Attempt to free unreferenced scalar at ./us2.pl line 264. Attempt to free unreferenced scalar at ./us2.pl line 282. Attempt to free unreferenced scalar at ./us2.pl line 264. Attempt to free unreferenced scalar at ./us2.pl line 282. Attempt to free unreferenced scalar at ./us2.pl line 263, <FOL> line 1 +2. Attempt to free unreferenced scalar at ./us2.pl line 282. Attempt to free unreferenced scalar at ./us2.pl line 263, <FOL> line 1 +3. 263 open (LISTA, "find $folder -type f|"); 264 while (my $lista = <LISTA>) { 265 $ile++; 266 if ($lista eq "") {print "Folder pusty\n";$dbh +->disconnect();exit 6;} 267 if ($lista =~ /S/) { $ile_starych++; } 268 } 269 close (LISTA); 270 271 #&licz_maile; 272 # $folder = $home . "/" . $fol_wzg . "/cur"; &licz_mail +e; 273 print "name_f",$kt,"\`=\`",$fol_wzg; 274 &sep_par; 275 print "all_mail",$kt,"\`=\`",$ile; 276 &sep_par; 277 print "new_mail",$kt,"\`=\`",$ile - $ile_starych; 278 &sep_par; 279 print "read_mail",$kt,"\`=\`",$ile_starych; 280 &sep_par; 281 $folder = $home . "/" . $fol_wzg; 282 open (DU, "du -s $folder|"); 283 my $temp = <DU>; 284 close (DU); -- Daniellek

Replies are listed 'Best First'.
Re: Attempt to free unreferenced scalar...
by Dominus (Parson) on Nov 29, 2000 at 19:06 UTC
    That error message usually indicates a bug in Perl. You should try to narrow down the problem by removing code from your program. Then when it is as small as you can make it while still demonstrating the problem, you should send a complete report to perlbug@perl.org

    One thing that sometimes causes this error are: Buggy XS modules. Another is when you try to do too much stuff in a signal handler function. Do you have any signal handlers in your program?

      Ok, i'll try narrowing code, and checking if it still crashes :)

      But still have a question: is it possible that buggy module can cause "my" error in the place of code where it is not used?

      And I don't do much with signal handlers in my code so I think it's not the problem (but I'll try to check this of course!)

      Thanks.

      -- Daniellek
        daniellek says:

        <blcokquote> > is it possible that buggy module can cause
        > "my" error in the place of code where it is not used?

        Yes, that's exactly why it is so hard to track down this sort of bug. Memory is corrupted in one place and then the probably does not manifest until later on.

Re: Attempt to free unreferenced scalar...
by mikfire (Deacon) on Nov 29, 2000 at 19:55 UTC
    The only time I have seen this error was in doing perl Gtk programming and it was usually a result of destroying an object without destroying the embedded objects first, ie, I would destroy the top window without destroying all the widgets I had embedded in it.

    When perl then went to DESTROY these objects when they went out of scope, it got very unhappy about attempting to free ( the embedded object ) an unreferenced scalar ( since the referencing object was already gone ).

    I am not claiming this isn't a bug, nor am I claiming this is your problem. I am merely offering my past experience hoping it may help.

    Mik
    mikfire

      I was getting this bug today and none of the pages I read helped so I figured I should post now that I figured out the problem. All pages I read indicate it's probably a perl bug itself. But for me it was due to having a foreach loop like this:

      foreach $key (keys %hash) {

      }

      with another foreach loop inside using the same variable name and same hash

      foreach $key (keys %hash) {
         foreach $key (keys %hash) {

         }
      }

      Incidentally, this only caused the problem in strict mode. I'm not saying this simple loop would replicate the problem, I got it down to about 20 lines and still throwing the error. But if you're getting this error message, look for a nested thing like that, it might be what's causing it. Perl should maybe throw a warning when a loops are nested like that with the same variables, because otherwie it was pretty hard to track down in my 1000 line program, I had to remove piece by piece until it became evident.

Re (tilly) 1: Attempt to free unreferenced scalar...
by tilly (Archbishop) on Nov 29, 2000 at 17:54 UTC
    Is there any reason that you don't do as perlsyn says and put an error check on your opens?
    open (LISTA, "find $folder -type f|") or die "Cannot find '$folder': $!";
    That may or may not solve your immediate problem, but it definitely solves A problem...

    And another thing, you are likely littering the process table with zombies. This may well be the cause of your loop crashing. You can either set a child handler, or you can start calling wait or waitpid to let your children exit. (If this guess is right then the error check should have noticed and pointed you in the right direction.)

    UPDATE
    I think I am wrong about the zombie guess. As mentioned below I suspect either memory corruption or a Perl bug. Using backticks to collect output may fix the program, but the bug should still be tracked down and reported.

      I don't use 'die', because this is not problem with opening "find"... I tried it some time ago, but script didn't die and "unreferenced..." where still there.

      I don't know if I understand second part of Your answer, but i need this script to be multithreaded...

      Thanks in advance for your patience :)

      -- Daniellek
        Please use die. Please, please, please. Even if it is not the problem this time, it is a really bad idea to leave production code sitting around without error checks left in. The majority of time and energy is spent on maintaining code, and error checks make a massive difference in either narrowing down what the problem is or what it isn't.

        As for the second part...(reads)...oops. I was giving advice based on my experiences with IPC::Open3, apparently on a straight piped open Perl does wait for you. In case you need to know that, when a child process is created and tries to die, it cannot finish dying until it tells its parent what its return status is. A process can wait in this last stage of death forever, and a process in that state is called a zombie. So if you spawn lots of children, then you have to check for them from time to time to avoid zombies.

        Still for your use, consider using `` to run the system commands and collect output. Less code, and the error checks are done for you.

        That may fix the problem, but still glancing in perldiag I see that your warning is supposed to indicate either a bug at the C level (in Perl or in an XS module) or else memory corruption. If you have no C modules you are going to and can reproduce the problem on another box, it is a Perl bug and you should use the perlbug utility to report it. First try to whittle it down to the smallest loop that you can which produces the problem. Then report it.