Skip to content

Instantly share code, notes, and snippets.

@jeanjerome
Forked from akostadinov/stack_trace.sh
Created March 3, 2024 08:22
Show Gist options
  • Save jeanjerome/b1fcb03966c2c70dfb7bb642219c88a5 to your computer and use it in GitHub Desktop.
Save jeanjerome/b1fcb03966c2c70dfb7bb642219c88a5 to your computer and use it in GitHub Desktop.
Get stack trace in Bash shell script/program.
# LICENSE: MIT, wtfpl or whatever OSS license you like
function get_stack () {
STACK=""
local i message="${1:-""}"
local stack_size=${#FUNCNAME[@]}
# to avoid noise we start with 1 to skip the get_stack function
for (( i=1; i<$stack_size; i++ )); do
local func="${FUNCNAME[$i]}"
[ x$func = x ] && func=MAIN
local linen="${BASH_LINENO[$(( i - 1 ))]}"
local src="${BASH_SOURCE[$i]}"
[ x"$src" = x ] && src=non_file_source
STACK+=$'\n'" at: "$func" "$src" "$linen
done
STACK="${message}${STACK}"
}
@jeanjerome
Copy link
Author

A better example from @RobertKrawitz solution :

#!/usr/bin/env bash

set -eE

function stack_trace() {
    local status_code="${1}" 

    local -a stack=("Stack trace of error code '${status_code}':")
    local stack_size=${#FUNCNAME[@]}
    local -i i
    local indent="    "
    # to avoid noise we start with 1 to skip the stack function
    for (( i = 1; i < stack_size; i++ )); do
        local func="${FUNCNAME[$i]:-(top level)}"
        local -i line="${BASH_LINENO[$(( i - 1 ))]}"
        local src="${BASH_SOURCE[$i]:-(no file)}"
        stack+=("$indent$src:$line ($func)")
        indent="${indent}    "
    done
    (IFS=$'\n'; echo "${stack[*]}")
}

trap 'stack_trace $?' ERR

doSomethingWrong() {
    ls -wrong-command
}

callFunction2() {
    doSomethingWrong
}

callFunction() {
    callFunction2
}

callFunction

which outputs:

bash-5.2$ ./test/test-trap.sh 
ls: invalid line width: ‘rong-command’
Stack trace of error code '2':
     └ ./test/test-trap.sh:26 (doSomethingWrong)
         └ ./test/test-trap.sh:30 (callFunction2)
             └ ./test/test-trap.sh:34 (callFunction)
                 └ ./test/test-trap.sh:37 (main)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment