我的基本代码:
proc A {} {B ; return 1}
proc B {} {C ; return 1}
proc C {} {return 1}
proc track {args} {
# some informations : [info frame -2]
}
# trace '::C' procedure
trace add execution C leave track
# call proc '::A'
A
我试图从这个回应中找到一些灵感。
我的目标是在调用此过程时获得被跟踪过程的所有父级(此处
proc ::C
)。track
程序能够返回这个:
::A call > ::B call > ::C
[info frame -2]
的回归给了我有趣的信息:
type source line 7 file /Users/mkn/temp/trace_test.tcl cmd C proc ::B level 1
但是我觉得这个命令只返回第一个父级。
根据您的确切意思,您所需要的基本信息来自
info level
或 info frame
命令。当您使用 uplevel
时,他们以非常重要的方式计算堆栈帧的概念有所不同; info frame
“看到”它,但info level
没有。
这两个命令在不带参数调用时都会给出堆栈帧的数量(在它们的意义上),你可以通过给出一个数字来识别它来获取堆栈帧的详细信息;
info level
返回特定级别的参数词列表(第一个词是命令名称),info frame
返回提供更精确信息的好东西字典。级别标识符在正数时从堆栈的一端开始计数,在负数时从另一端开始计数。我可以永远记住哪一个零是!
对于您要尝试做的事情,我猜
info level
会更容易一些。获取过程调用框架列表的长度,在框架编号上向上计数(或向下计数?),使用 info level
将它们映射到单词列表,然后使用 lindex
选择每个单词的第一个单词。最后用合适的join
.做出你想要的结果
proc track {call args} {
set cmds {}
for {set i 1} {$i<[info level]} {incr i} {
lappend cmds [lindex [info level $i] 0]
}
# Because this is a leave trace we also need
lappend cmds [lindex $call 0]
puts [join $cmds " call > "]
}
额外的
lappend
是因为调用离开跟踪发生在调用帧刚刚被取消堆叠时。 (info frame
不同的看法。)
我主要用
info frame
来检索的是调用者的源文件和行号。这对于日志记录非常有用,而且实际上并没有被其他任何东西可靠地报告。 (技术上也不在这里,但动态生成的代码通常不需要直接登录。)