TCL 如何在哪个文件和哪一行执行命令?

tcl how to get command executed in which file and which line?

提问人:JoshTitle 提问时间:10/5/2023 最后编辑:Donal FellowsJoshTitle 更新时间:10/5/2023 访问量:50

问:

如何知道我何时获取tcl脚本,哪个proc / eval在哪个文件中执行以及哪一行?

以下是我的代码:

 set counts     [info frame];
 set frame_list [info frame [expr {$counts - 2}] ]   ; #for cmd type is "eval"
 set frame_list [info frame [expr {$counts - 1}] ]   ; #for cmd type is other like "source"
 [dict get $frame_list file] # to get file
 [dict get $frame_list line] # to get line in file

但是有时在脚本中,文件中有内部评估,让frame_list获取错误级别信息。 如何让TCL得到正确的file&line?

TCL 堆栈框架

评论


答:

3赞 Cyan Ogilvie 10/5/2023 #1

我认为您想要 ,它(以可观的性能成本)允许额外的记帐以在更多情况下解析帧的文件和行号:interp debug {} -frame true

没有:

proc dothing script {
    eval $script
}

proc foo {} {
    dothing {
        puts "In dothing: [info frame 0]"
    }
}

foo

指纹In dothing: type eval line 2 cmd {info frame 0} proc ::dothing level 0

使用 debug -frame true:

interp debug {} -frame true

proc dothing script {
    eval $script
}

proc foo {} {
    dothing {
        puts "In dothing: [info frame 0]"
    }
}

foo

指纹In dothing: type source line 9 file /home/cyan/git/research/tcl/frame/without.tcl cmd {info frame 0} proc ::dothing level 0

(Tcl 能够将帧转换为报表中的帧,因为它有足够的信息来自 )。type evaltype sourceinterp debug {} -frame true

但是,在许多情况下,仍然无法做到这一点:

interp debug {} -frame true

proc dothing script {
    eval $script
}

proc foo {} {
    set s {
        puts "In dothing: [info frame 0]"
    }
    dothing $s
}

foo

静态打印In dothing: type eval line 2 cmd {info frame 0} proc ::dothing level 0

这个例子(在包含源文件中定义的字符串文字的变量上计算)可能可以通过 Tcl 核心中的足够工作来解决(我有以这种方式将脚本跟踪回文字的实验),但总会有一些其他例子是不可能的(比如正在运行的脚本是通过网络套接字接收的 - 它只是一个值,没有文件中的源位置,或由其他代码动态构建的脚本)。因此,没有通用的方法可以始终获取帧报告。type source

另请注意,在 interp 上启用帧调试是单向操作 - 一旦启用,它就会保持启用状态,无法再次关闭它。因此,如果您正在从事性能很重要的事情,请注意性能影响。

0赞 Donal Fellows 10/5/2023 #2

有时,运行时根本不知道文件和行信息。对于任何生成的代码尤其如此;它只是不与特定的源位置相关联。(还有其他情况确实如此,但我现在不记得了,除非在处理加密代码时,这在普通的 Tcl 解释器中不会发生。

当你使用 时,你只需要知道许多键不一定在那里。info frame