有时您无法理解变量值何时更改。并且有必要通过在变量上放置一个观察点来找到该行。如何做到这一点?TCL trace 命令可以用来获取修改变量的行吗?
问问题
175 次
1 回答
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<)"
}
}
}
}
随意尝试!
于 2011-04-24T16:05:24.987 回答