On Tue, 9 Jun 2015 18:02:31 +0200, Jean Delvare wrote: > I built bash 4.3.39 with --without-bash-malloc and then ran the daemon > under valgrind for 1 minute. The back trace for the leak is: > > 3,973 bytes in 430 blocks are definitely lost in loss record 1,610 of 1,613 > at 0x4C277AB: malloc (in > /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) > by 0x471A2A: xmalloc (xmalloc.c:112) > by 0x461A84: array_variable_name (arrayfunc.c:917) > by 0x457731: parameter_brace_expand_word (subst.c:5785) > by 0x452DA4: param_expand (subst.c:7385) > by 0x4550E9: expand_word_internal (subst.c:8393) > by 0x4566DB: call_expand_word_internal.constprop.14 (subst.c:3299) > by 0x456829: expand_string_assignment (subst.c:3387) > by 0x4509DB: expand_string_if_necessary (subst.c:3092) > by 0x450E3E: do_assignment_internal (subst.c:2823) > by 0x45859E: expand_word_list_internal (subst.c:2912) > by 0x4360B7: execute_simple_command (execute_cmd.c:4000) > > I do not have a minimum test case yet, but I wanted to ask if the back > trace above provides enough hints to recognize an already know bug and > the commit that fixed it?
I think I have a minimal test case now: #!/bin/bash declare -a ARRAY ARRAY[0]=foo FOO=${ARRAY[0]} # <-- leaks echo $FOO And a candidate fix: bash 4.3: Fix memory leak in parameter_brace_expand_word Fix a memory leak in function parameter_brace_expand_word. If expanding an array reference and PF_ASSIGNRHS is set, function array_variable_name is called but the allocated string is not needed and is ignored. It must be freed before going on, otherwise memory is leaked. Function array_variable_part does that for us so just call it instead of function array_variable_name (as is done in later versions of bash.) --- subst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- a/subst.c +++ b/subst.c @@ -5782,7 +5782,7 @@ expand_arrayref: /* XXX - does this leak if name[@] or name[*]? */ if (pflags & PF_ASSIGNRHS) { - temp = array_variable_name (name, &tt, (int *)0); + temp = array_variable_part (name, &tt, (int *)0); if (ALL_ELEMENT_SUB (tt[0]) && tt[1] == ']') temp = array_value (name, quoted|Q_DOUBLE_QUOTES, 0, &atype, &ind); else -- Jean Delvare SUSE L3 Support