Hello.

I am writing a complex Bash script which on failure prints a stack
trace.  After upgrading to Bash 5.3.0 I noticed a strange change of
behaviour in BASH_SOURCE which I believe is a bug.

While FUNCNAME has the correct content, BASH_SOURCE does not match it
element-by-element as intended.  I see that the first element of
BASH_SOURCE, describing the outermost frame, is defined correctly while
the others, which should contain the name of the same source file, are
empty.
It is not shown here but BASH_LINE_NO is also correct.

This is my test case script, also attached.

--8<---------------cut here---------------start------------->8---
#!/usr/bin/env bash

f ()
{
    echo -n 'FUNCNAME:     '
    for i in $(seq 0 $(( "${#FUNCNAME[@]}" - 1)) ); do
        echo -n "'${FUNCNAME[$i]}' "
    done
    echo

    echo -n 'BASH_SOURCE:  '
    for i in $(seq 0 $(( "${#BASH_SOURCE[@]}" - 1)) ); do
        echo -n "'${BASH_SOURCE[$i]}' "
    done
    echo
}

g ()
{
    local i="$1"
    if test "$i" == 0; then
        f
    else
        g $(( "$i" - 1 ))
    fi
}

echo "BASH_VERSION: $BASH_VERSION"
g 3
--8<---------------cut here---------------end--------------->8---

The function f prints a stack trace, for simplicity starting from
the innermost frame.
The function g calls itself recursively with a decremented value
of its parameter unless the parameter is zero, in which case it
calls f.
At the top level I call g with a small nonzero parameter.

Now, with Bash 5.2.37 I see what was expected: the innermost
frame is a call to f, before that g was called a few times,
from g itself and at the beginning from the top level.  The
definitions of f and g are all in the script.

--8<---------------cut here---------------start------------->8---
[luca@hennessy ~]$ ./bash-stack-trace 
BASH_VERSION: 5.2.37(1)-release
FUNCNAME:     'f' 'g' 'g' 'g' 'g' 'main' 
BASH_SOURCE:  './bash-stack-trace' './bash-stack-trace' './bash-stack-trace' 
'./bash-stack-trace' './bash-stack-trace' './bash-stack-trace' 
--8<---------------cut here---------------end--------------->8---

which is expected.

But with 5.3.0 I get:
--8<---------------cut here---------------start------------->8---
[luca@hennessy ~]$ ~/usr-pEp/bin/bash ./bash-stack-trace 
BASH_VERSION: 5.3.0(1)-release
FUNCNAME:     'f' 'g' 'g' 'g' 'g' 'main' 
BASH_SOURCE:  '' '' '' '' '' './bash-stack-trace' 
--8<---------------cut here---------------end--------------->8---

Notice that FUNCNAME elements are empty, but the array size is
correct and matches BASH_SOURCE (and BASH_LINENO).

Best regards,

-- 
Luca Saiu      https://ageinghacker.net
  GNU Jitter     https://www.gnu.org/software/jitter
  GNU epsilon    https://www.gnu.org/software/epsilon
  pEp-mail-tool  https://codeberg.org/pEp/pEp-mail-tool

I support everyone's freedom of mocking any opinion or belief, no
matter how deeply held, with open disrespect and the same unrelented
enthusiasm of a toddler who has just learned the word "poo".

Attachment: bash-stack-trace
Description: Binary data

Attachment: sender_key.asc
Description: application/pgp-keys

Reply via email to