0

I greatly benefit from having a stack traceback in my bash scripts. However, there was always the periodic glitch that I just ignored until I took the time today to make a minimal working example:

#!/bin/bash                        # 1
set -o errexit                     # 2
set -o errtrace                    # 3
trap 'stacktrace' ERR              # 4
function bad(){                    # 5
    return 1; }                    # 6
function good(){ bad; }            # 7
function stacktrace(){             # 8
echo "Lines  = ${BASH_LINENO[*]}"  # 9
echo "Funcs  = ${FUNCNAME[*]}"     #10
}                                  #11
function mymain(){                 #12
    good                           #13
}                                  #14
echo "$BASH_VERSION"               #15
mymain                             #16

# call tree:
#-------------
# mymain
#     good
#         bad
#             return 1
#-------------------
# output is:
#-------------------
# 4.3.46(1)-release
# Lines  = 6 13 16 0
# Funcs  = stacktrace good mymain main

I kinda would have expected that the error trap would have been triggered on line 7 when bad() returns an error code, but OK, bash has its many little ways. The real problem is, I can't see enough information here to give a correct stack traceback. Line #7 in function good() must surely be part of the stack traceback for this error, no matter how you cut it.

I can imagine some really nasty workaround for this, but hopefully I'm missing something and someone can point out how to correctly identify line #7 as part of the stack traceback in this situation.

My fear is that this is unfortunate bash behavior, that it has popped bad() from the stack before triggering the trap but also before popping the current line# to the caller (line #7), effectively ending up reporting that line #6 belongs to good() rather than to bad().

Ron Burk
  • 6,058
  • 1
  • 18
  • 20
  • First part: `return 1` isn't an error. Imagine `good() { if bad; then :; fi; }` - clearly `ERR` shouldn't be triggered. That being said, I do get the correct line 7 on the top of the stack on Bash 4.4. I wonder if Bash 4.3 is incorrectly "inlining" `bad` into `good` - does this still happen if you write `good() { :; bad; }`? – ephemient Apr 25 '17 at 20:44
  • Yes, still happens (and has happened for a goodly amount of time in bash scripts that are, I hesitate to admit, thousands of lines big). Thank you for trying that; sounds like I most likely have to wait for 4.4 to make it into my favorite distributions. – Ron Burk Apr 25 '17 at 22:46

0 Answers0