[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
execute_perl leaks memory, patched
Hi,
I noticed that execute_perl() in perl.c leaks memory after a while... If
you use a timer in a script with a short interval it will eat up quite alot,
it chewed up 128MB over a day for me with a timer interval at 100ms...
Anyway, i wrote a patch that uses perl_call_args instead of perl_eval_pv,
it still evaluates the perl function so that an error will be caught and
printed out instead of crashing xchat... Tell me what you think, here's
the diff -ur1 patch for xchat 1.7.7
/Martin
________________________________________
Ladda ner det senaste från Passagens Filarkiv http://tucows.passagen.se/
--- perl.c Mon Jun 4 14:23:51 2001
+++ perl.c.new Thu Jun 14 00:22:49 2001
@@ -267,27 +267,40 @@
*/
-static SV *
+
+/*
+ 2001/06/14: execute_perl replaced by Martin Persson <mep@passagen.se>
+ previous use of perl_eval leaked memory, replaced with
+ a version that uses perl_call instead
+*/
+int
execute_perl (char *function, char *args)
{
- static char *perl_cmd = NULL;
- static char *perl_format = {
- "{\n"
- "my $__result__;\n"
- "eval {\n;"
- "$__result__ = &%s('%s');\n"
- "};\n"
- "return $__result__ unless $@;"
- "IRC::print(\"\\cbPerl error:\\cb $@\\n\");"
- "return 1;\n"
- "}\n"
- };
-
- if (perl_cmd)
- free (perl_cmd);
- perl_cmd = malloc (strlen (function) + strlen (args) * 2 + strlen(perl_format) + 1);
- sprintf (perl_cmd, perl_format, function, escape_quotes (args));
-#ifndef HAVE_PERL_EVAL_PV
- return (perl_eval_pv (perl_cmd, TRUE));
-#else
- return (Perl_eval_pv (perl_cmd, TRUE));
-#endif
+ char *perl_args[2] = { args, NULL }, buf[512];
+ int count, ret_value = 1;
+ SV *sv;
+
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(sp);
+ count = perl_call_argv(function, G_EVAL | G_SCALAR, perl_args);
+ SPAGAIN;
+
+ sv = GvSV(gv_fetchpv("@", TRUE, SVt_PV));
+ if (SvTRUE(sv)) {
+ snprintf(buf, 512, "Perl error: %s\n", SvPV(sv, PL_na));
+ PrintText(perl_sess, buf);
+ POPs;
+ } else if (count != 1) {
+ snprintf(buf, 512, "Perl error: expected 1 value from %s, "
+ "got: %d\n", function, count);
+ PrintText(perl_sess, buf);
+ } else {
+ ret_value = POPi;
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ return ret_value;
}
@@ -482,3 +495,3 @@
struct _perl_inbound_handlers *data;
- SV *handler_return;
+ int handler_return;
@@ -494,5 +507,5 @@
handler_return = execute_perl (data->handler_name, buf);
- if (SvIV (handler_return))
+ if (handler_return)
{
- return SvIV (handler_return);
+ return handler_return;
}
@@ -508,3 +521,3 @@
struct _perl_inbound_handlers *data;
- SV *handler_return;
+ int handler_return;
@@ -522,5 +535,5 @@
handler_return = execute_perl (data->handler_name, buf);
- if (SvIV (handler_return))
+ if (handler_return)
{
- return SvIV (handler_return);
+ return handler_return;
}
@@ -540,3 +553,3 @@
char nullargs[] = "";
- SV *handler_return;
+ int handler_return;
int command = FALSE;
@@ -579,6 +592,6 @@
}
- if (SvIV (handler_return))
+ if (handler_return)
{
free (command_name);
- return SvIV (handler_return);
+ return handler_return;
}
@@ -598,3 +611,3 @@
char *args;
- SV *handler_return;
+ int handler_return;
@@ -645,6 +658,6 @@
}
- if (SvIV (handler_return))
+ if (handler_return)
{
free (args);
- return SvIV (handler_return);
+ return handler_return;
}