Version 8 of List the call stack

Updated 2016-09-14 20:28:50 by dkf

The following will list the entire call stack at entry to a proc or method.

    proc x {a} {
       puts "Entered x, args $a"
       set distanceToTop [info level]
       for {set i 1} {$i < $distanceToTop} {incr i} {
          set callerlevel [expr {$distanceToTop - $i}]
          puts "CALLER $callerlevel: [info level $callerlevel]"
      }
    # ...
       return
    }

KPV Here's another version which prints out argument values (even default one). (See also Pstack.)

proc stacktrace {} {
    set stack "Stack trace:\n"
    for {set i 1} {$i < [info level]} {incr i} {
        set lvl [info level -$i]
        set pname [lindex $lvl 0]
        append stack [string repeat " " $i]$pname
        foreach value [lrange $lvl 1 end] arg [info args $pname] {
            if {$value eq ""} {
                info default $pname $arg value
            }
            append stack " $arg='$value'"
        }
        append stack \n
    }
    return $stack
}

# Testing code

proc A { } {
    B 3
}
proc B { x } {
    C [incr x] 2
}
proc C { x y {z 5} } {
    D [incr x] [incr y] $z
}
proc D { x y z} {
    E [incr x] [incr y] [incr z]
}
proc E {x y z } {
    stacktrace
}
A

Napier notes that the above solutions will not work if you are using TclOO as info args my will result in an error.

DKF: Yes, there's other mechanisms for introspecting TclOO methods on the stack. The self method command when run in the right stack scope will be useful, as will info class definition and/or info object definition: self method says what is running, and info class definition is like info args and info body rolled into one. (Methods aren't quite procedures. They're just very similar.)