trace获取所有父类添加执行命令

问题描述 投票:0回答:1

我的基本代码:

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

但是我觉得这个命令只返回第一个父级。

tcl
1个回答
0
投票

根据您的确切意思,您所需要的基本信息来自

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
来检索的是调用者的源文件和行号。这对于日志记录非常有用,而且实际上并没有被其他任何东西可靠地报告。 (技术上也不在这里,但动态生成的代码通常不需要直接登录。)

© www.soinside.com 2019 - 2024. All rights reserved.