bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Function declarations produce no trace nor trigger debug trap while havi


From: Erik Adelbert
Subject: Function declarations produce no trace nor trigger debug trap while having side effects
Date: Thu, 27 Oct 2022 17:33:39 +0200

Configuration Information [Automatically generated, do not change]:
Machine: aarch64
OS: darwin21.6.0
Compiler: clang
Compilation CFLAGS: -DSSH_SOURCE_BASHRC
uname output: Darwin rio 21.5.0 Darwin Kernel Version 21.5.0: Tue Apr 26 
21:08:29 PDT 2022; root:xnu-8020.121.3~4/RELEASE_ARM64_T8101 arm64
Machine Type: aarch64-apple-darwin21.6.0

Bash Version: 5.2
Patch Level: 2
Release Status: release

Description:
We have found that 
[https://www.gnu.org/software/bash/manual/bash.html#Shell-Functions shell 
function] _declarations_:
0 do not emit trace output
0 do not call DEBUG trap
0 modify $?

Unless we have missed the related documentation, we believe the current 
semantic to be at least unclear and would like to see either:
0 the DEBUG trap called _before_ any function declaration (preferred)
0 or function declarations preserving $? as they are not commands appearing in 
trace and DEBUG (has cons)

Repeat-By:
Thanks to @soliton on #iirc, we have a straightforward one-liner:

+verbatim+
1 ❯ bash -xc 'PS4="+(\$?) "; false; f() { :; }; echo end'
2 + PS4='+($?) '
3 +(0) false
4 +(0) echo end
5 end
-verbatim-

f() declaration takes place in between line #3 and #4. The declaration itself 
evades the trace but still its exit status (0) replaces the one from false (1) 
(line #4).

Here is another example showing that function declarations also escape DEBUG 
trap while having the same side effect on $?:
+verbatim+
 1 ❯ cat main.bash
 2    #!/bin/env bash
 3
 4    set -o functrace 
 5    trap 'echo "DEBUG> ($?) ${BASH_COMMAND}";' DEBUG
 6    
 7    f() {
 8        : f/start
 9        false
10        # g()(( 0 ))
11        : f/survived
12    }
13    
14    f && : top/success
15
16 ❯ bash ./main.bash
17    DEBUG> (0) f
18    DEBUG> (0) f
19    DEBUG> (0) : f/start
20    DEBUG> (0) false
21    DEBUG> (1) : f/survived
22    DEBUG> (0) : top/success
23 ❯ sed -i '' 's/# g/g/' main.bash
24 ❯ bash ./main.bash
25    DEBUG> (0) f
26    DEBUG> (0) f
27    DEBUG> (0) : f/start
28    DEBUG> (0) false
29    DEBUG> (0) : f/survived
30    DEBUG> (0) : top/success
-verbatim-

* When enabling functrace (line #4), the DEBUG trap becomes inherited by 
functions.
* The DEBUG trap itself prints the _previous_ command exit status and the 
_next_ command.
* During the first run (line #16), g() definition is commented out (line #10). 
* The exit status (1) of false (line #9) appears in the output (line #21).
* The sed command (line #23) uncomment g() definition (line #10).
* During the second run (line #24). The exit status (1) of false is no longer 
available: It has been replaced by 0 (line #29), thanks to the successful 
declaration of g() (line #10).
* Just as before, the function declaration itself evades debugging (ie. It is 
never loaded in $BASH_COMMAND).

We have traced this behaviour back to 
[http://git.savannah.gnu.org/cgit/bash.git/tree/execute_cmd.c#n6109 
execute_intern_function()]. This function has no support for tracing nor 
trapping DEBUG.

Should you consider to go on and discuss a solution, we will be happy to help.

Best regards,
erik





reply via email to

[Prev in Thread] Current Thread [Next in Thread]