@@ -512,25 +512,53 @@ DO_WITH_DEBUG() {
512512 return " $exit_status "
513513}
514514
515- # Trace the current script and function.
515+ # TRACE_FUNC outputs the function call stack in a readable format.
516+ # It helps debug the execution path leading to the current function.
517+ #
518+ # The format of the output is:
519+ # main(/path/to/script:line) -> function1(/path/to/file:line) -> function2(/path/to/file:line)
520+ #
521+ # Usage:
522+ # Call TRACE_FUNC within any function to print the call hierarchy.
516523TRACE_FUNC () {
517- # Index [1] for BASH_SOURCE and FUNCNAME give us the caller location.
518- # FUNCNAME is 'main' if called from a script outside any function.
519- # BASH_LINENO is offset by 1, it provides the line that the
520- # corresponding FUNCNAME was _called from_, so BASH_LINENO[0] is the
521- # location of the caller.
522- TRACE " ${BASH_SOURCE[1]} (${BASH_LINENO[0]} ): ${FUNCNAME[1]} "
524+ local i stack_trace=" "
525+
526+ # Traverse the call stack from the earliest caller to the direct caller of TRACE_FUNC
527+ for (( i= ${# FUNCNAME[@]} - 1 ; i> 1 ; i-- )) ; do
528+ stack_trace+=" ${FUNCNAME[i]} (${BASH_SOURCE[i]} :${BASH_LINENO[i-1]} ) -> "
529+ done
530+
531+ # Append the direct caller (without extra " -> " at the end)
532+ stack_trace+=" ${FUNCNAME[1]} (${BASH_SOURCE[1]} :${BASH_LINENO[0]} )"
533+
534+ # Print the final trace output
535+ TRACE " ${stack_trace} "
523536}
524537
525- # Show the entire current call stack in debug output - useful if a catastrophic
526- # error or something very unexpected occurs, like totally invalid parameters.
538+ # DEBUG_STACK prints the entire call stack for debugging purposes.
539+ # This function provides more detailed output than TRACE_FUNC, which is useful
540+ # for diagnosing errors, tracking function calls, or understanding unexpected behavior.
541+ #
542+ # The output format:
543+ # call stack: (N frames)
544+ # - 0 - /path/to/file(line): function_name
545+ # - 1 - /path/to/file(line): function_name
546+ #
547+ # Usage:
548+ # Call DEBUG_STACK anywhere to display the full stack trace.
527549DEBUG_STACK () {
528- local FRAMES
529- FRAMES=" ${# FUNCNAME[@]} "
530- DEBUG " call stack: ($(( FRAMES - 1 )) frames)"
531- # Don't print DEBUG_STACK itself, start from 1
532- for i in $( seq 1 " $(( FRAMES - 1 )) " ) ; do
533- DEBUG " - $(( i - 1 )) - ${BASH_SOURCE[$i]} (${BASH_LINENO[$((i - 1))]} ): ${FUNCNAME[$i]} "
550+ local SKIP_FIRST=0
551+
552+ # If TRACE_FUNC called DEBUG_STACK, remove it from the stack to avoid redundancy.
553+ [[ " ${FUNCNAME[1]} " == " TRACE_FUNC" ]] && SKIP_FIRST=1
554+
555+ # Get the total number of stack frames
556+ local FRAMES=" ${# FUNCNAME[@]} "
557+ DEBUG " call stack: ($(( FRAMES - 1 - SKIP_FIRST)) frames)"
558+
559+ # Iterate through the stack and print each function call with file and line number
560+ for i in $( seq $(( 1 + SKIP_FIRST)) " $(( FRAMES - 1 )) " ) ; do
561+ DEBUG " - $(( i - 1 - SKIP_FIRST)) - ${BASH_SOURCE[$i]} (${BASH_LINENO[$((i - 1))]} ): ${FUNCNAME[$i]} "
534562 done
535563}
536564
0 commit comments