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

All, I'm making calls to eval_pv in an application with an embedded interpreter. The final code was leaking memory, so I chopped it down to the point where I have only a call to eval_pv in a tight loop:
#include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; main (int argc, char **argv, char **env) { STRLEN n_a; int i; char *embedding[] = { "", "-e", "0" }; my_perl = perl_alloc(); perl_construct( my_perl ); perl_parse(my_perl, NULL, 3, embedding, NULL); perl_run(my_perl); for(i=0; i < 10000000; i++) { eval_pv("1", TRUE); } perl_destruct(my_perl); perl_free(my_perl); }
This doesn't create any variables in perl space (I don't think) and I throw away the SV* returned by eval_pv. Watching memory use as it runs, this still leaks memory compiled agains perl 5.8.3 and 5.6.1. As an experiment, I tried eval_sv with:
#include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; main (int argc, char **argv, char **env) { STRLEN n_a; int i; SV* my_string; char *embedding[] = { "", "-e", "0" }; my_perl = perl_alloc(); perl_construct( my_perl ); perl_parse(my_perl, NULL, 3, embedding, NULL); perl_run(my_perl); my_string = newSVpv("2", 0); for(i=0; i < 10000000; i++) { eval_sv(my_string, TRUE); } perl_destruct(my_perl); perl_free(my_perl); }
which leaks in the same way. However, if I use call_pv instead, this doesnt leak at all:
#include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; main (int argc, char **argv, char **env) { STRLEN n_a; int i; char *embedding[] = { "", "-e", "sub fred {1;};" }; my_perl = perl_alloc(); perl_construct( my_perl ); perl_parse(my_perl, NULL, 3, embedding, NULL); perl_run(my_perl); for(i=0; i < 10000000; i++) { dSP; ENTER; SAVETMPS; PUSHMARK(sp); call_pv("fred", G_DISCARD); SPAGAIN; LEAVE; } perl_destruct(my_perl); perl_free(my_perl); }
This seems fairly fundamental, so I must missing something. In my application, it is possible that eval_pv be called a large number of times (hundreds of millions). Any ideas? Many thanks!

Replies are listed 'Best First'.
Re: memory leak in eval_pv?
by Trizor (Pilgrim) on May 15, 2007 at 16:58 UTC

    eval_*(...) take the same flags as their cousins call_*(...) in that you must specify G_DISCARD to discard the return value of the eval or you'll leak SV's with refcount one.

    Update: After speaking with ysth I learned that eval_pv(...) doesn't care about G_DISCARD. While my initial diagnosis was correct, you're not freeing the SV returned by eval_*(...), a solution that works is:

    SvREFCNT_dec(eval_pv(...));

      Hi Trizor, Many thanks for your reply - alas this did not seem to fix the leak. The code I have now is:
      #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; main (int argc, char **argv, char **env) { STRLEN n_a; int i; char *embedding[] = { "", "-e", "sub fred {1;};" }; my_perl = perl_alloc(); perl_construct( my_perl ); perl_parse(my_perl, NULL, 3, embedding, NULL); perl_run(my_perl); for(i=0; i < 10000000; i++) { SvREFCNT_dec(eval_pv("1;", TRUE)); } perl_destruct(my_perl); perl_free(my_perl); }
      and compiled with perl 5.8.3 still leaks. In a previous attempt (before I posted) I tried assigning the eval_pv() to an SV* and explicitly calling SV_free on it (and also setting it mortal with sv_2motral) but neither of these helped. I was coming to the conclusion that the leak may be inside eval_pv/sv iteself so I thought I'd post here to see if anyone else had seen similar issues. I guess the thing to try next is to build the latest 5.8.8 perl and try it with that. Many thanks, Shaun.
        Just to wrap this one up.... It appears that eval_pv (and eval_sv) return a mortal SV* that must be cleaned up by "topping and tailing" the call to eval_pv with:
        ENTER; SAVETMPS; value = (eval_pv("1;", TRUE)); FREETMPS; LEAVE;
        The assignment SV* value is required, else errors about freeing unreferenced value are generated. Shaun.