2016-07-31 3 views
1

I持って次のスクリプト、~/tmp/2.tclTCL実行のトレースがコンパイル関数で停止しないのはなぜですか?

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

set a [p1 200] 

私は私が "./tclsh8.6 ~/tmp/2.tcl" を発行したときにTCLの実行内で何が起こっているかを追跡したいと、デバッグビルドTCLのv8.6.1を持っているので、私は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. 

は、私がここで何を欠場か?なぜスクリプトがコンパイルされていないのですか?

#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 

[UPDATE]私が間違って何が起こっていたかわからない、今のブレークポイントがトリガされますか:ここで

はTclEvalExを実行しているのバックトレースです。

+0

括弧のついて、最初の引数は 'if'(' while'と 'for'への2番目の引数)は' expr'セッションとして評価されていますので、 'if {$ a + 10> 100} ... '十分である –

答えて

1

コンパイラはかなりの数の内部のエントリポイントを持っている - それはどのような方法パブリックAPIでではありませんし、それを発表する誰もなしに変更の対象となる - とTclSetByteCodeFromAnyTclCompileScriptはあなたが見逃しているものの一つであるように見えます。他にもあります。それらをすべてリストするのは実際は厄介です。コンパイラが使用する構造体の設定に使用される標準的な内部関数であるTclInitCompileEnvにブレークポイントを設定する必要があります。それをと呼ぶ何でもが興味深いでしょう。


FWIW、procへの呼び出しは、プロシージャの本体をコンパイルしません。これは、コードが必要になるまで、すなわちプロシージャが呼び出されるまで延期されます。あなたが見ていたTclEvalExの呼び出しは、直接意味のある編集を直接行うことはありません。 また、Tcl 8.6。*で使われている非再帰的実行エンジンは、多くのをgdbのようなツールでデバッグするのが難しくなります。 CスタックはTclスタックをまったく反映しません。

幸運。

+0

Tcl 8.6。*で使われている非再帰的な実行エンジンは、gdbのようなツールでデバッグするのがずっと難しくなっているというあなたの言うところに興味を持っています。 –

+1

*以前は、各手続き呼び出しがいくつかのスタックフレームをCスタックに置くことになり、いくつかのTclコマンドもそうすることになりました。 Tcl 8の前に戻ると、直接の対応があり、デバッガはTclの正確さを確認することができました。それはバイトコードコンパイラで少し変わったが、あなたはそれをかなりよく理解することができた。 8.6のNREエンジンはそれを吹き飛ばします。あなたは通常、CスタックとTclスタックの間にはまったく関係がありません。デバッグ性を向上させる方法を探している人がいましたが、がんで亡くなりました。 –

関連する問題