Working on a bash function call stack trace…
Script traps errors and runs a callStack()
function. But on trapping, It always shows a call stack for the callStack()
function itself instead of the function where the trap occurred as in …
/share/sbin/zimdialog: line 647: status: command not found
Function call stack ( command.function() ) ...
/share/sbin/zimdialog.main()
/share/sbin/include.callStack()
Looking to get a stack trace that includes the errantFunction()
like…
/share/sbin/zimdialog: line 647: status: command not found
Function call stack ( command.function() ) ...
/share/sbin/zimdialog.main()
/share/sbin/zimdialog.errantFunction()
/share/sbin/include.callStack()
The trap is coded as…
trap callStack HUP INT QUIT TERM ERR
The callStack()
function is coded as…
function callStack () {
{ isNotNull "$1" && isHelp "$1"; } && {
helpShow 'callStack
Diagnostics regarding where the call to this function came from'
return
}
local T="${T} "
local STACK=
i=${#FUNCNAME[@]}
((--i))
printf "${T}Function call stack ( command.function() ) ...\n" >&2
T="${T} "
while (( $i >= 0 ))
do
STACK+="${T}${BASH_SOURCE[$i]}.${FUNCNAME[$i]}()\n"
T="${T} "
((--i))
done
printf "$STACK" >&2
}
Supplemental: set -E, etc. not working
In /share/sbin/gshlib
…
set -e
set -E
set -T
shopt -s extdebug
trap $(callStack) ERR
function initialize () {
:
logstatus #<<< ERROR FOR TESTING trap
}
export -f initialize
Misnaming logStatus
to logstatus
within /share/sbin/gshlib.initialize()
to spring the trap ERR
, the best I get is…
Function call stack ...
| /share/sbin/archive.main()
| /share/sbin/include.include()
| /share/sbin/gshlib.source()
| /share/sbin/include.callStack()
/share/sbin/gshlib: line 109: logstatus: command not found
What I'm looking to get is…
Function call stack ...
| /share/sbin/archive.main()
| /share/sbin/include.include()
| /share/sbin/gshlib.source()
| /share/sbin/gshlib.initialize()
| /share/sbin/include.callStack()
/share/sbin/gshlib: line 109: logstatus: command not found
Best Answer
You need to
set -E
(orset -o errtrace
) so that thetrap ERR
is inherited by called functions.Once you do that, you'll probably find that you'll get a cascading error report, since each function in the call stack will be terminated (with a non-zero exit code) by the script error.
ERR
is not triggered by invocation of a shell function in a context where failure is not considered fatal (likeif
orwhile
). In such a context, the stack trace will probably not appear, although I'm not sure how version-specific that is.