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: Sat, 10 May 2014 23:28:19 +0300
User-agent: Heirloom mailx 12.5 6/20/10

> Date: Fri, 9 May 2014 17:28:50 -0400 (EDT)
> From: Jan Chaloupka <address@hidden>
> To: Aharon Robbins <address@hidden>
> Cc: address@hidden
> Subject: Re: [bug-gawk] : in debug mode, every eval causes double free of
>  memory
>
> Hi,
>
> after further investigation of the free problem, does not look like
> a double free anymore. free_context frees all instruction pools,
> destroy_symbol free one symbol from symbol table. Some instruction
> can refer to this symbol but that is the only connection.  Output from
> valgrind reports to independent situations:
>
> ==23928== Invalid free() / delete / delete[] / realloc()
> ==23928==    at 0x4C28577: free (in 
> /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==23928==    by 0x456510: r_format_val (node.c:254)
> ==23928==    by 0x46992B: str_exists (awk.h:1281)
> ==23928==    by 0x46A6F8: remove_symbol (awk.h:1769)
> ==23928==    by 0x46A758: destroy_symbol (symbol.c:232)
> ==23928==    by 0x42FF64: do_eval (debug.c:5569)
> ==23928==    by 0x425B2B: zzparse (command.y:170)
> ==23928==    by 0x430ED0: debug_prog (debug.c:2834)
> ==23928==    by 0x40AB43: main (main.c:741)
>
>
> ==23928==  Address 0x570b600 is 32 bytes inside a block of size 128 free'd
> ==23928==    at 0x4C28577: free (in 
> /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==23928==    by 0x46B493: free_context (symbol.c:858)
> ==23928==    by 0x42FF58: do_eval (debug.c:5567)
> ==23928==    by 0x425B2B: zzparse (command.y:170)
> ==23928==    by 0x430ED0: debug_prog (debug.c:2834)
> ==23928==    by 0x40AB43: main (main.c:741)
>
> After looking to str_exists function, there is force_string functions which 
> looks like this:
>
> static inline NODE *
> force_string(NODE *s)
> {
>       if ((s->flags & STRCUR) != 0
>                   && (s->stfmt == -1 || s->stfmt == CONVFMTidx)
>       )
>               return s;
>       return format_val(CONVFMT, CONVFMTidx, s);
> }
>
> Well, for @eval node, format_val functions is called, which does not
> make any sense, since there is no value to be printed. Setting this:
>
> diff --git a/debug.c b/debug.c
> index b55f357..ea7db0d 100644
> --- a/debug.c
> +++ b/debug.c
> @@ -5565,8 +5565,11 @@ 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)
> +       if (ret_val != NULL) {
> +                f->flags |= STRCUR;
> +                f->stfmt = -1;
>                 destroy_symbol(f);      /* destroy "@eval" */
> +        }
>         return false;
>  }
>
> solves invalid free problem. But still invoking eval "" for the second time 
> reports:
>
> $ ./gawk -f /dev/null --debug
> gawk> eval ""
> gawk> eval ""
> gawk: cmd. line:1: error: function name address@hidden' previously defined
>
> From awkgram.y on line 390 install_function is called, inside of which
> after second eval "" we get not NULL lookup. So after destroy_symbol(f),
> @eval symbol should be removed from function_table as well. Besides
> after above patch, remove_symbol always returns NULL because @eval is
> installed into function_table, not symbol_table.
>
> Jan

Thanks for the additional report. I believe the below is the correct
fix, against what's in the git repo. Please let me know how it
fares against valgrind. I can't test that at the moment.

Thanks,

Arnold
--------------------------
diff --git a/debug.c b/debug.c
index 32b308a..67ad56d 100644
--- a/debug.c
+++ b/debug.c
@@ -5567,14 +5567,12 @@ 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 */
 
-       /*
-        * 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"
-        */
+       if (ret_val != NULL) {
+               NODE *s = make_string("@eval", 5);
+
+               (void) assoc_remove(func_table, s);
+               unref(s);
+       }
 
        free_srcfile(the_source);
 



reply via email to

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