[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Error message garbage when parameter expansion used inside (()) and
From: |
PRussell |
Subject: |
Re: Error message garbage when parameter expansion used inside (()) and variable unset |
Date: |
Tue, 3 Apr 2018 18:07:08 -0500 |
Hi,
The error seems to be localized to the expansion of PS4 when "set -x" is active.
Please see sample script below.
I am aware of the unusual parameter expansion for FUNCNAME. There might be a
local historical reason. :-)
It does not happen outside of the PS4 expansion. It also behaves differently on
4.3 vs 4.4.
On 4.4, valgrind shows "Invalid Reads".
On 4.3, valgrind shows no errors.
I included below a small part of valgrind's output. If you need more let me
know.
Sample script:
.....................................
#!/bin/bash
function main() {
# Shows different successful parameter expansions of FUNCNAME
echo -n 'declare -p FUNCNAME:'
declare -p FUNCNAME
# parentheses surrounding expansion
echo '(${FUNCNAME:+${FUNCNAME[0]##*/}})':"(${FUNCNAME:+${FUNCNAME[0]##*/}})"
# parentheses inside expansion
echo '${FUNCNAME:+(${FUNCNAME[0]##*/})}':"${FUNCNAME:+(${FUNCNAME[0]##*/})}"
echo
# PS4: Use FUNCNAME in PS4 - parentheses surrounding expansion *No ERROR*
declare -x PS4='+ ${BASH_SOURCE[0]##*/} line ${LINENO}
(${FUNCNAME:+${FUNCNAME[0]}}):'
declare -p PS4
echo "PS4=${PS4}"
set -x; var=0;var1=var; (( var1 == $var2 )) && echo yes || echo no
echo
# PS4: Use FUNCNAME in PS4 - parentheses inside expansion **ERROR HERE**
declare -x PS4='+ ${BASH_SOURCE[0]##*/} line ${LINENO}
${FUNCNAME:+(${FUNCNAME[0]})}:'
declare -p PS4
echo "PS4=${PS4}"
set -x; var=0;var1=var; (( var1 == $var2 )) && echo yes || echo no
}
main
.....................................
Partial valgrind output:
.....................................
==759== Memcheck, a memory error detector
==759== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==759== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==759== Command: ./x19
==759==
declare -p FUNCNAME:declare -a FUNCNAME=([0]="main" [1]="main")
${FUNCNAME:+(${FUNCNAME[0]##*/})}:(main)
(${FUNCNAME:+${FUNCNAME[0]##*/}}):(main)
${FUNCNAME[0]##*/}:(main)
${FUNCNAME[0]}:(main)
${FUNCNAME}:(main)
declare -x PS4="+ \${BASH_SOURCE[0]##*/} line \${LINENO}
(\${FUNCNAME:+\${FUNCNAME[0]}}):"
PS4=+ ${BASH_SOURCE[0]##*/} line ${LINENO} (${FUNCNAME:+${FUNCNAME[0]}}):
==759== Invalid read of size 16
==759== at 0x533D488: __wcsnlen_sse4_1 (in /usr/lib/libc-2.26.so)
==759== by 0x532D5C2: wcsrtombs (in /usr/lib/libc-2.26.so)
==759== by 0x128D4C: ??? (in /usr/bin/bash)
==759== by 0x160243: ??? (in /usr/bin/bash)
==759== by 0x160B96: ??? (in /usr/bin/bash)
==759== by 0x161D0D: ??? (in /usr/bin/bash)
==759== by 0x1637FB: expand_prompt_string (in /usr/bin/bash)
==759== by 0x12D530: decode_prompt_string (in /usr/bin/bash)
==759== by 0x13BD92: indirection_level_string (in /usr/bin/bash)
==759== by 0x13C078: xtrace_print_assignment (in /usr/bin/bash)
==759== by 0x15CD12: ??? (in /usr/bin/bash)
==759== by 0x165835: ??? (in /usr/bin/bash)
==759== Address 0x5935610 is 0 bytes after a block of size 16 alloc'd
==759== at 0x4C2CEDF: malloc (vg_replace_malloc.c:299)
==759== by 0x532C5EF: wcsdup (in /usr/lib/libc-2.26.so)
==759== by 0x128BB9: ??? (in /usr/bin/bash)
==759== by 0x160243: ??? (in /usr/bin/bash)
==759== by 0x160B96: ??? (in /usr/bin/bash)
==759== by 0x161D0D: ??? (in /usr/bin/bash)
==759== by 0x1637FB: expand_prompt_string (in /usr/bin/bash)
==759== by 0x12D530: decode_prompt_string (in /usr/bin/bash)
==759== by 0x13BD92: indirection_level_string (in /usr/bin/bash)
==759== by 0x13C078: xtrace_print_assignment (in /usr/bin/bash)
==759== by 0x15CD12: ??? (in /usr/bin/bash)
==759== by 0x165835: ??? (in /usr/bin/bash)
==759==
==759== Invalid read of size 16
==759== at 0x533D48D: __wcsnlen_sse4_1 (in /usr/lib/libc-2.26.so)
==759== by 0x532D5C2: wcsrtombs (in /usr/lib/libc-2.26.so)
.....................................
--
Peggy Russell
On 04/03/2018 01:15 PM, Chet Ramey wrote:
> I don't see the same type of memory corruption. I get:
>
> chet-mail(1)$ lsb_release -d
> Description: Red Hat Enterprise Linux Server release 6.9 (Santiago)
> chet-mail(1)$ cat ./x18
> ( set -x;var=0;var1=var; (( var1 == $var2 )) && echo yes || echo no )
> chet-mail(1)$ ./bash -c 'echo $BASH_VERSION'
> 4.4.19(4)-release
> chet-mail(1)$ ./bash ./x18
> + var=0
> + var1=var
> + (( var1 == ))
> ./x18: line 1: ((: var1 == : syntax error: operand expected (error token
> is "== ")
> + echo no
> no
>
> But otherwise the results are correct.
>
> If you'd like, take a look at running your version under valgrind or a
> similar tool to see if bash is touching freed memory. (I don't happen to
> see that running on RHEL, but your results may vary with a distribution-
> compiled version.)