Skip to content

Commit 280cb1f

Browse files
committed
functions: Improve TRACE_FUNC and DEBUG_STACK: provide full call stack traces in output
Signed-off-by: Thierry Laurion <[email protected]>
1 parent 6279500 commit 280cb1f

File tree

1 file changed

+43
-15
lines changed

1 file changed

+43
-15
lines changed

initrd/etc/functions

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
516523
TRACE_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.
527549
DEBUG_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

Comments
 (0)