I ran the configure script with the following arguments: hp% ./configure CC=gcc-6 CFLAGS='-Wall -g -ggdb -O0 -fsanitize=address' LDFLAGS=-fsanitize=address --without-bash-malloc
Which enables the LeakSanitizer (https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer). It detected the following memory leak: hp% ./bash -c ': & wait' ================================================================= ==5784==ERROR: LeakSanitizer: detected memory leaks Direct leak of 2 byte(s) in 1 object(s) allocated from: #0 0x7f0ec8737d28 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.3+0xc1d28) #1 0x559e5096b6cb in xmalloc /home/dualbus/local/src/gnu/bash/xmalloc.c:112 #2 0x559e508aa246 in execute_simple_command /home/dualbus/local/src/gnu/bash/execute_cmd.c:4105 #3 0x559e50899914 in execute_command_internal /home/dualbus/local/src/gnu/bash/execute_cmd.c:802 #4 0x559e508a19a9 in execute_connection /home/dualbus/local/src/gnu/bash/execute_cmd.c:2581 #5 0x559e5089a6e9 in execute_command_internal /home/dualbus/local/src/gnu/bash/execute_cmd.c:971 #6 0x559e5097c900 in parse_and_execute /home/dualbus/local/src/gnu/bash/builtins/evalstring.c:443 #7 0x559e5086597f in run_one_command /home/dualbus/local/src/gnu/bash/shell.c:1399 #8 0x559e50863eaa in main /home/dualbus/local/src/gnu/bash/shell.c:724 #9 0x7f0ec7eca2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0) SUMMARY: AddressSanitizer: 2 byte(s) leaked in 1 allocation(s). The leak is in line 4105, since the savestring function is called (which just a strcpy/malloc wrapper), but the allocated memory is not FREE'd. hp% cat -n execute_cmd.c|sed -n '4100,4110p' 4100 vast majority of cases. */ 4101 maybe_make_export_env (); 4102 4103 /* Don't let a DEBUG trap overwrite the command string to be saved with 4104 the process/job associated with this child. */ 4105 if (make_child (savestring (the_printed_command_except_trap), async) == 0) 4106 { 4107 already_forked = 1; 4108 simple_command->flags |= CMD_NO_FORK; 4109 4110 subshell_environment = SUBSHELL_FORK; /* XXX */ The issue is more evident when running long commands: # This will start chewing chunks of ~2MB hp% bash -c 'while :; do : "$(printf '%.sx' {1..2097152})" & wait; done' I think the fix is easy, since we just have to store the result of savestring in a temporary pointer, so that we can later call FREE(p). -- Eduardo Bustamante https://dualbus.me/