bug-gawk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [bug-gawk] : in debug mode, every eval causes double free of memory


From: Aharon Robbins
Subject: Re: [bug-gawk] : in debug mode, every eval causes double free of memory
Date: Fri, 09 May 2014 11:47:08 +0300
User-agent: Heirloom mailx 12.5 6/20/10

Hi.  Concerning this:

> Date: Tue, 06 May 2014 15:44:36 +0200
> From: Jan Chaloupka <address@hidden>
> To: address@hidden
> Subject: [bug-gawk] : in debug mode, every eval causes double free of memory
>
> Hi,
>
> every time a gawk is started in debug mode, eval command is run 
> correctly, but then double free of memory occurs. Occurs on Fedora 20.
>
> Steps to reproduce:
>
> 1) gawk -f /tmp/emptygawk.awk --debug
> 2) type eval ""
>
> /tmp/emptygawk.awk is empty file.
>
> Reported in https://bugzilla.redhat.com/show_bug.cgi?id=1089073.
>
> I've been able to trace the problem to debug.c:5567 and debug.c:5569. 
> free_context frees memory. destroy_symbol then frees it for the second 
> time. But why it is happening, it requires deeper knowledge of the 
> source code.
>
> Regards
> Jan

Thanks for the report and the subsequent information (valgrind) etc.
Thanks also to Andy Schorr and Nelson Beebe for on- and off-list help.

I was able to reproduce this on an Ubuntu 14.04 system at work. I installed
Ubuntu 14.04 on an old laptop at home and then was able to track it down.

In the process, valgrind saw another memory leak, which I fixed too. Here
is the combined diff. It will make its way to the repo shortly.

Arnold

diff --git a/awk.h b/awk.h
index 5f42093..6544840 100644
--- a/awk.h
+++ b/awk.h
@@ -1372,6 +1372,7 @@ extern NODE *stopme(int nargs);
 extern void shadow_funcs(void);
 extern int check_special(const char *name);
 extern SRCFILE *add_srcfile(enum srctype stype, char *src, SRCFILE *curr, bool 
*already_included, int *errcode);
+extern void free_srcfile(SRCFILE *thisfile);
 extern void register_deferred_variable(const char *name, NODE 
*(*load_func)(void));
 extern int files_are_same(char *path, SRCFILE *src);
 extern void valinfo(NODE *n, Func_print print_func, FILE *fp);
diff --git a/awkgram.y b/awkgram.y
index 7d530b7..07131d2 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -2333,6 +2333,15 @@ parse_program(INSTRUCTION **pcode)
        return (ret || errcount);
 }
 
+/* free_srcfile --- free a SRCFILE struct */
+
+void
+free_srcfile(SRCFILE *thisfile)
+{
+       efree(thisfile->src);
+       efree(thisfile);
+}
+
 /* do_add_srcfile --- add one item to srcfiles */
 
 static SRCFILE *
diff --git a/debug.c b/debug.c
index 84e69d4..c9cb049 100644
--- a/debug.c
+++ b/debug.c
@@ -5448,6 +5448,7 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
        int ecount = 0, pcount = 0;
        int ret;
        int save_flags = do_flags;
+       SRCFILE *the_source;
        
        if (prog_running) {
                this_frame = find_frame(0);
@@ -5458,7 +5459,7 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
        ctxt = new_context();
        ctxt->install_func = append_symbol;     /* keep track of newly 
installed globals */
        push_context(ctxt);
-       (void) add_srcfile(SRC_CMDLINE, arg->a_string, srcfiles, NULL, NULL);
+       the_source = add_srcfile(SRC_CMDLINE, arg->a_string, srcfiles, NULL, 
NULL);
        do_flags = false;
        ret = parse_program(&code);
        do_flags = save_flags;
@@ -5466,6 +5467,7 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
        if (ret != 0) {
                pop_context();  /* switch to prev context */
                free_context(ctxt, false /* keep_globals */);
+               free_srcfile(the_source);
                return false;
        }
 
@@ -5565,8 +5567,17 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED)
 
        pop_context();  /* switch to prev context */
        free_context(ctxt, (ret_val != NULL));   /* free all instructions and 
optionally symbols */
-       if (ret_val != NULL)
-               destroy_symbol(f);      /* destroy "@eval" */
+
+       /*
+        * May 2014:
+        * Don't do this. f points into the context we just released.
+        * Only showed up on Fedora 20 / Ubuntu 14.04.
+        *
+        * if (ret_val != NULL)
+        *      destroy_symbol(f);      // destroy "@eval"
+        */
+
+       free_srcfile(the_source);
        return false;
 }
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]