Version 9 of List the call stack

Updated 2016-09-14 20:31:11 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 class/self method command when run in the right stack scope will be useful, as will info class definition and/or info object definition: self class and self method say 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.)