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

Perl 5.10 eval($string) memory leak

by fuzzmonkey (Sexton)
on Aug 15, 2013 at 16:37 UTC ( [id://1049624]=perlquestion: print w/replies, xml ) Need Help??

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

Greetings Monks, I'm learning about genetic algorithms and I am working with a script that searches random strings for executable code. The problem with eval($string) in perl 5.10 is that strings that fail to execute correctly leave a bit of memory locked up. I can't run the script for very long because it causes a memory leak. I've searched around for a solution but I really want to continue evaluating random strings for nuggets of executable code. I can't upgrade to a newer version of Perl on this machine either. Is there some way to capture a reference to eval($string) and undef it? Would that free the memory?

I'm working with OpenBSD 4.4 and it's default of Perl 5.10.

Thanks!

Replies are listed 'Best First'.
Re: Perl 5.10 eval($string) memory leak
by tobyink (Canon) on Aug 15, 2013 at 16:42 UTC

    Even if you're unable to upgrade your system perl, you ought to be able to install a newer perl in your home directory using perlbrew.

    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
Re: Perl 5.10 eval($string) memory leak
by dave_the_m (Monsignor) on Aug 15, 2013 at 21:32 UTC
    Historically, eval has tended to leak if it traps an error during compilation (errors during execution should be ok). The range of things that leak have been whittled down over the years, and 5.18.0 includes an OP arena facility that should should have removed most, if not all, of the remaining leaks.

    Dave.

Re: Perl 5.10 eval($string) memory leak
by BrowserUk (Patriarch) on Aug 15, 2013 at 18:07 UTC

    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.

      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.

        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
Re: Perl 5.10 eval($string) memory leak
by betterworld (Curate) on Aug 15, 2013 at 19:04 UTC

    I don't know what kind of random code you are evaluating. Certainly it is possible to write code that occupies memory by means of global variables. You can avoid that using Safe.

    Or fork.

      Or by manually cleaning the symbol table.
      لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      Hey thanks for telling me about Safe I have not read about that module before. It will come in handy!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1049624]
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (6)
As of 2024-04-26 09:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found