[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);
- Re: [bug-gawk] : in debug mode, every eval causes double free of memory, (continued)
- Re: [bug-gawk] : in debug mode, every eval causes double free of memory, Aharon Robbins, 2014/05/09
- Re: [bug-gawk] : in debug mode, every eval causes double free of memory, Jan Chaloupka, 2014/05/09
- Re: [bug-gawk] : in debug mode, every eval causes double free of memory, Aharon Robbins, 2014/05/09
- Re: [bug-gawk] : in debug mode, every eval causes double free of memory, Jan Chaloupka, 2014/05/09
- Re: [bug-gawk] : in debug mode, every eval causes double free of memory,
Aharon Robbins <=
- Re: [bug-gawk] : in debug mode, every eval causes double free of memory, Jan Chaloupka, 2014/05/10
- Re: [bug-gawk] : in debug mode, every eval causes double free of memory, Andrew J. Schorr, 2014/05/11