为什么我对 TCL 执行的跟踪不停留在编译函数上



我有以下脚本,~/tmp/2.tcl

proc p1 {a} {
    if {[expr $a + 10] > 100} {
        puts hi
    }
}
set a [p1 200]

我有一个调试构建的TCL v8.6.1,我喜欢在发出" ./tclsh8.6 ~/tmp/2.tcl"时跟踪TCL执行内部发生的事情,所以我使用gdb来跟踪执行(在gdb,set args ~/tmp.2.tcl,(

令我困惑的是:

1. In `TclEvalEx`(), it is command by command parsing and execution, I do not see any
script/command compiling.
2. I set breakpoints at `TclAttemptCompileProc(), TclCompileObj()` and `TclCompileExpr`(), 
they are not triggered.

我在这里错过了什么?为什么没有任何脚本编译?

以下是运行TclEvalEx的回溯:

#0  TclEvalEx (interp=0x613680, script=0x674950 "proc p1 {a} {n    if {[expr $a + 10] > 100} {n        puts hin    }n}nnset a [p1 200]nn", numBytes=87, flags=0, line=1, clNextOuter=0x0, 
    outerScript=0x674950 "proc p1 {a} {n    if {[expr $a + 10] > 100} {n        puts hin    }n}nnset a [p1 200]nn") at ~/tcl8.6.1/source/generic/tclBasic.c:4935
#1  0x00007ffff7af0812 in Tcl_FSEvalFileEx (interp=0x613680, pathPtr=0x65beb0, encodingName=0x0) at ~/tcl8.6.1/source/generic/tclIOUtil.c:1809
#2  0x00007ffff7afb88f in Tcl_MainEx (argc=-1, argv=0x7fffffffde08, appInitProc=0x400963 <Tcl_AppInit>, interp=0x613680) at ~/tcl8.6.1/source/generic/tclMain.c:417
#3  0x000000000040095c in main (argc=2, argv=0x7fffffffddf8) at ~/tcl8.6.1/source/unix/tclAppInit.c:84

[更新] 我不确定出了什么问题,现在断点确实被触发了。

编译器

有很多内部入口点——它绝不是一个公共 API,并且在没有人宣布的情况下可能会进行更改——TclSetByteCodeFromAnyTclCompileScript似乎是你错过的入口点之一。还有其他人;将它们全部列出实际上很尴尬。您可能应该在TclInitCompileEnv上设置断点,这是用于设置编译器使用的结构的标准内部函数;任何调用它的东西都会引起您的兴趣。


FWIW,对proc的调用不会编译过程的主体。这被推迟到需要代码,即,直到调用过程。您看到的对TclEvalEx的调用不会直接进行太多有意义的编译。此外,Tcl 8.6.* 中使用的非递归执行引擎使得使用 gdb 等工具进行调试变得更加困难。C 堆栈根本不反映 Tcl 堆栈。

祝你好运。

最新更新