有时您无法理解变量值何时发生变化。并且有必要通过在变量上设置观察点来找到该行。怎么做到这一点? TCL跟踪命令可以用来获取修改变量的行吗?
答案 0 :(得分:4)
要在变量上放置观察点,请使用trace
命令。您可以通过info
命令获取有关变量分配的上下文的扩展信息,特别是level
和frame
子命令。 (后者仅从Tcl 8.5开始提供。)
像这样把事情放在一起应该提供你想要的信息:
trace add variable x write peekLocation
proc peekLocation args {
puts "WRITTEN FROM >[info level -1]< CALL"
puts "DETAILS: [info frame -1]"
}
# Demonstration...
proc foobar {} {
global x
set x "jibber jabber"
}
foobar
它不会完全工作;您可以轻松找到变量更新时正在运行的过程,但在该过程中,更新发生的位置仍然遥不可及。 (您可以看到跟踪回调本身的调用,或者在堆栈的更高层,调用执行操作的过程,这两个都没有用...)
[编辑]:一种不同的方法是假设哪个命令正在进行更新(例如,set
)并做一些jiggery-pokery以便info level
(唯一可以执行的命令)提供一个行号)可以做正确的事情:
rename set __orig_set;proc set args {doTrace;uplevel 1 [list __orig_set {*}$args]}
# Separate the probe from the instrumentation
proc doTrace {} {
puts [info frame -2]
}
有效。将其扩展到其他设置变量的命令(例如[incr],[lappend],[lset])也相当容易。一个更高级的探测器就是:
proc doTrace {} {
__orig_set f [info frame -2]
dict with f {
switch $type {
source {
puts "Write happened on line $line of file $file"
}
proc {
puts "Write happened on line $line of procedure $proc"
}
default {
puts "Write happened on line $line (command was >$cmd<)"
}
}
}
}
随意尝试!