我有以下脚本~/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 hi\n }\n}\n\nset a [p1 200]\n\n", numBytes=87, flags=0, line=1, clNextOuter=0x0,
outerScript=0x674950 "proc p1 {a} {\n if {[expr $a + 10] > 100} {\n puts hi\n }\n}\n\nset a [p1 200]\n\n") 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
[更新] 我不确定出现了什么问题,现在断点确实被触发了。
答案 0 :(得分:1)
编译器有很多内部入口点 - 它不是以任何方式一个公共API,并且在没有任何人宣布的情况下可以进行更改 - 并且TclSetByteCodeFromAny
和TclCompileScript
似乎是您错过的。还有其他人;把它们列出来真的很尴尬。您可能应该在TclInitCompileEnv
上设置断点,这是用于设置编译器使用的结构的标准内部函数;任何调用它都会引起您的兴趣。
FWIW,对proc
的调用并没有编译程序的主体。这被推迟到需要代码,即,直到调用该过程。您所看到的对TclEvalEx
的调用不会直接进行有意义的编译。
此外,Tcl 8.6。*中使用的非递归执行引擎使得使用像gdb这样的工具更难以调试很多。 C堆栈根本不反映Tcl堆栈。