Dear Perl-XS-Gurus,

I have a very simple piece of code which does almost nothing except
printing "Hello World" from a perl interpreter invoked from C. This is
just a cooked down version of the real problem, which involves
exchanging data between Perl and C.

The problem is that this code leaks memory (as you might have guessed
from the subject ;-)
In it's simplest form it starts a perl interpreter (all code directly
from  'man perlembed' ) and does a while(1)-loop over printing a
string in the perl interpreter. You can watch it grow if you put a
sleep()-statement in it: about every 30th call to eval_pv() it grows
by 4 byte which is not _that_ much a problem but on the one hand this
is only cooked down code from the original problem-program and on the
other hand the program which is going to use this is supposed to run
for (at least) weeks without a restart.. 

I already tried the perl-monks but they couldn't help.
The discussion thread is here:
http://perlmonks.org/index.pl?node_id=74985


Any help or suggestions _highly_ appreciated (actually I'm supposed to
have this ready today, but a little fix here and there must be
possible later ...)

Regards
Stefan Kamphausen



The Code:
=========

Version 1
---------
One instance of perl and a call to perl_eval_pv in the loop


/* compile with */
/* gcc -o getconf getconf.c `perl -MExtUtils::Embed -e ccopts -e ldopts` */

/* I tried this under Perl 5.6.0 and perl 5.005_3 */
   
# include <stdio.h>
# include <EXTERN.h>
# include <perl.h>
# include <unistd.h>

void call_perl(void);
static PerlInterpreter *my_perl;

int main(int argc, char **argv, char **env)
{
   char *embedding[] = { "", "-e", "0" };
   long int i=0;
   my_perl = perl_alloc();
   perl_construct(my_perl);
   perl_parse(my_perl, NULL, 3, embedding, NULL);
   perl_run(my_perl);

   /* In a loop we leak */
   PL_perl_destruct_level = 1;  /* this is from perlmonks discussion */
   while (1) {
          printf("%ld ",i++);
          call_perl();
          /* sleep(1); */
   }
   perl_destruct(my_perl);
   perl_free(my_perl);
}

void call_perl(void) {
   eval_pv("print \"Hello World\\n\"",TRUE);
}




Version 2
---------
Built and destruct a perl instance for every call. Well, this _should_
cleanup everything, or not?

/* compile with */
/* gcc -o monk monk.c `perl -MExtUtils::Embed -e ccopts -e ldopts` */

/* I tried this under Perl 5.6.0 and perl 5.005_3 */
   
# include <stdio.h>

# include <EXTERN.h>
# include <perl.h>
# include <unistd.h>

void call_perl();

int main(int argc, char **argv, char **env)
{
   /* The Leaking Loop */
   while (1) {
          call_perl();
          sleep(1);
   }
}

void call_perl(void) {

   static PerlInterpreter *my_perl;
   char *embedding[] = { "", "-e", "0" };
   
   my_perl = perl_alloc();
   perl_construct(my_perl);
   perl_parse(my_perl, NULL, 3, embedding, NULL);
   perl_run(my_perl);

   eval_pv("print \"Perl Version: $]\\n\"",TRUE);
   perl_destruct(my_perl);
   perl_free(my_perl);

}




-- 
Stefan Kamphausen              <[EMAIL PROTECTED]>
                                   http://www.skamphausen.de
Novel Science International GmbH
____________________________________________________________

Postfach    2944                 Tel:   +49 551 / 50 41 6- 0
37019 Goettingen                 Fax:   +49 551 / 50 41 6-99
Germany                          http://www.novelscience.com

Reply via email to