in reply to Perl 5.10 eval($string) memory leak

I realise this can be both platform specific (I'm using 5.10.1 on Windows), and can depend a lot on what you are evaling; but this creates and evals a million x 100 term expressions and shows no sign of a memory leak. The memory stays glued to 2.5MB for the whole run.

Maybe you could post a sample of the stuff you're evaling?


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
  • Comment on Re: Perl 5.10 eval($string) memory leak

Replies are listed 'Best First'.
Re^2: Perl 5.10 eval($string) memory leak
by fuzzmonkey (Sexton) on Aug 15, 2013 at 19:49 UTC

    Here is the simplest example of what I'm playing with.

    #!/usr/bin/perl use strict; my $DOWARN = 0; BEGIN { $SIG{'__WARN__'} = sub { warn $_[0] if $DOWARN } } my $symbol_list = "symbolsV1p1.dat"; my @symbol_pool = (); my $symbol_size = 0; my $index = 0; my $seed = "while "; my $embryo = $seed; my $MAX_ITER = 10; my $i = 0; my $result = undef; print "test.pl started...\n"; # Open my file list of symbols and functions # I will randomly jumble around and eval. open(SYMBOLS, "<$symbol_list") or die "Could not open $symbol_list: $! +\n"; while (<SYMBOLS>) { chomp $_; print "symbol_pool character is: $_\n"; push(@symbol_pool, $_); } close(SYMBOLS); $index = int(rand($symbol_size)); print "Initial embryo is:\n$embryo\n"; while (1) { $embryo = $embryo . $symbol_pool[$index] . ";"; $result = eval($embryo); # Print out the successful string eval's if ($result != undef) { print "\n\nA working one liner has been generated!\n"; print "$embryo\n"; print "Line: $i\n\n"; $i++; } # Truncate the string to keep it from growing infinitely long if (length($embryo) >= 80) { $embryo = $seed; } # Stop the script after I get a few successful string eval's if ($i == $MAX_ITER) { print "Program finished\n"; exit(0); } $index = int(rand($symbol_size)); }

      Not so useful without (a sample of) the symbols file.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        Here you go ^_^

        + - / * ^ \ $ @ % ! & ( ) { } [ ] print printf open eval close while foreach for if else unless / . ~ ` ' ; " ' A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 0 ' ' " " '\n'

      Wouldn't it make sense to move your first occurrence of:

      $index = int(rand($symbol_size));

      ... inside the while loop (right at the top of the loop), and then remove the occurrence at the end of the loop?

      That is, not:

      foo(); while (1) { bar(); foo(); }

      But instead:

      while (1) { foo(); bar(); }

      It should have the same effect; be more compact and avoid repetition.

      Anyway, I believe the reason you're leaking memory is that your evaluated strings can end up containing variables, and those variables are not lexicals, so they get stored in the package stash.

      package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name

        Yeah the code that is being generated needs to be more constrained. I can't just throw any kind of garbage at it and believe it will get thrown away properly without my help. Thanks for the help!