Next: , Previous:   [Contents][Index]

38 Debugging


38.1 Source Level Debugging

Maximaは、組み込みのソースレベルデバッガを持っています。 ユーザーは、関数にブレイクポイントを設定でき、 そこから行毎に実行することができます。 そのレベルでバインドされた変数と一緒にコールスタックを検査することができます。

コマンド:helpまたは:hは、 デバッガーコマンドのリストを示します。 (一般的に、 もし略字がただ1つなら、コマンドは略せます。 もしただ1つでないなら、選択肢がリストされます。) デバッガー内では、 変数と式を検査し、定義し、操作するために、ユーザーは任意の通常のMaxima関数も使うことができます。

Maximaプロンプトで、 :brコマンドで ブレイクポイントが設定できます。 デバッガー内では、 ユーザーは、 :n (“next”)コマンドを使って1度に1行進むことができます。 :bt (“backtrace”)コマンドは、スタックフレームのリストを示します。 :r (“resume”)コマンドは、デバッガーから抜けて、実行を続けます。 以下の例で、これらのコマンドを例示します。

(%i1) load ("/tmp/foobar.mac");

(%o1)                           /tmp/foobar.mac

(%i2) :br foo
Turning on debugging debugmode(true)
Bkpt 0 for foo (in /tmp/foobar.mac line 1) 

(%i2) bar (2,3);
Bkpt 0:(foobar.mac 1)
/tmp/foobar.mac:1::

(dbm:1) :bt                        <-- :bt typed here gives a backtrace
#0: foo(y=5)(foobar.mac line 1)
#1: bar(x=2,y=3)(foobar.mac line 9)

(dbm:1) :n                         <-- Here type :n to advance line
(foobar.mac 2)
/tmp/foobar.mac:2::

(dbm:1) :n                         <-- Here type :n to advance line
(foobar.mac 3)
/tmp/foobar.mac:3::

(dbm:1) u;                         <-- Investigate value of u
28

(dbm:1) u: 33;                     <-- Change u to be 33
33

(dbm:1) :r                         <-- Type :r to resume the computation

(%o2)                                1094

ファイル/tmp/foobar.macは以下の通りです:

foo(y) := block ([u:y^2],
  u: u+3,
  u: u^2,
  u);
 
bar(x,y) := (
  x: x+2,
  y: y+2,
  x: foo(y),
  x+y);

EMACSを通してのデバッガーの使用

もしユーザーがシェルウィンドウ(dblシェル)で、GNU emacsの下でコードを走らせているか、 グラフィカルならインターフェイスバージョンXmaximaを走らせているなら、 もしブレイクポイントで停止させたら、 ウィンドウの他の半面に表示されるソースファイルの中に、 赤でハイライトされたか、右行を示す小さな矢印で 現在位置を見るでしょう。 M-n (Alt-n)をタイプすることで、一度に一行進めることができます。

Emacsの下では、 dblシェルの中で走らせなければいけません。 dblシェルは、elispディレクトリの中に dbl.elファイルを要求します。 elispファイルをインストールしたか、Maxima elispディレクトリをパスに足したかを確認してください: 例えば、以下を .emacsファイルかsite-init.elに足してください。

(setq load-path (cons "/usr/share/maxima/5.9.1/emacs" load-path))
(autoload 'dbl "dbl")

すると、emacsの中で、

M-x dbl

は、例えば、Maxima, gcl, gbbなどのプログラムを走らせることができるシェルウィンドウを開始するでしょう。 このシェルウィンドウはソースレベルデバッグや 他のウィンドウのソースコードの表示についても知っています。

ユーザーは、 C-x spaceをタイプすることで ファイルのある行に ブレイクポイントを設定できます。 これは、カーソルがどの関数の中かがわかり、 カーソルが示すその関数のどの行かわかります。 もしカーソルが、例えば、fooの行2なら、 fooを二番目の行でブレイクするために、 他のウィンドウの中で、コマンド“:br foo 2”を挿入します。 これをイネーブルにするには、 ユーザーは ファイルfoobar.macが訪れるウィンドウの中で maxima-mode.elを機能させなければいけません。 Alt-Control-xをタイプすることで 関数をMaximaに評価ような、 そのファイルウィンドウで利用可能な追加のコマンドがあります。


38.2 Keyword Commands

キーワードコマンドは、Maxima式として解釈(interpret)されない特殊キーワードです。 キーワードコマンドは、ブレイクプロンプトではできませんが、Maximaプロンプトやデバッガープロンプトで入力できます。 キーワードコマンドはコロン’:’で始まります。 例えば、Lisp形を評価するには、 may type :lispの後に評価される形式をタイプします。

(%i1) :lisp (+ 2 3) 
5

取られる引数の数は、特定のコマンドに依存します。 コマンド全体をタイプする必要はありません、ただブレイクキーワードの中で唯一であれば十分です。 例えば、:br:breakのために十分です。

キーワードコマンドは以下にリストされます。

:break F n

関数Fの中に関数の頭から行オフセットnで ブレイクポイントを設定します。 もしFが文字列として与えられたら、 ファイルと仮定され、nはファイルの頭からのオフセットです。 オフセットはオプションです。 もし与えられないなら、ゼロと仮定されます。 (関数かファイルの最初の行。)

:bt

スタックフレームのバックトレイスを印字します。

:continue

計算を継続します。

:delete

指定されたブレイクポイントを、もし指定されないならすべてのブレイクポイントを削除します。

:disable

指定されたブレイクポイントを、もし指定されないならすべてのブレイクポイントをディセーブルにします。

:enable

指定されたブレイクポイントを、もし指定されないならすべてのブレイクポイントをイネーブルにします。

:frame n

スタックフレームnを、もし指定されないなら現在のフレームを印字します。

:help

デバッガーコマンドに関するヘルプを印字します。 もし指定されないなら、コマンドすべてのヘルプを印字します。

:info

項目についての情報を印字します。

:lisp some-form

some-formをLisp形式として評価します。

:lisp-quiet some-form

Lisp形式some-formを出力せずに評価します。

:next

:nextは関数コールをステップオーバーする点を除いて、 :stepのようなものです。

:quit

計算を完了せずに、 現在のデバッガーレベルから抜けます。

:resume

計算を継続します。

:step

新しいソー行に至るまで計算を継続します。

:top

計算を完了せずに(任意のデバッガーレベルから)Maximaプロンプトに戻ります。


Previous: , Up: Debugging   [Contents][Index]

38.3 Functions and Variables for Debugging

オプション変数: debugmode

デフォルト値: false

もしdebugmodetrueなら、 Maximaのエラーが起こった時Maximaはデバッガーを開始します。 ユーザーはコールバックを検査したり、ブレイクポイントを設定したり、Maximaコードをステップ実行したりなど コマンドを入力することができます。 デバッガーコマンドのリストに関しては、 debuggingを参照してください。

debugmodeをイネーブルにしても、Lispのエラーは捕らえられません。

オプション変数: refcheck

デフォルト値: false

refchecktrueの時、 Maximaは 計算の中で、バイドされた変数が最初に使われる度にメッセージを印字します。

オプション変数: setcheck

デフォルト値: false

もしsetcheckが(添字付きでもよい)変数のリストに設定されているなら、 Maximaは 変数またはそれらの添字付き出現が通常の割り当て演算子:::割り当て演算子、 または関数引数バインドでバインドされた時 (しかし関数割り当て:=やマクロ割り当て::=演算子でバインドされた時以外) はいつでも、 メッセージを印字します。 メッセージは変数名とバインドされた値から構成されます。

setcheckは、 allまたはtrueに設定することができ、 それによって、すべての変数を含みます。

setcheckの新しい要素のそれぞれは、 チェックする変数の新しいリストを確立し、 以前setcheckに割り当てられたいかなる変数も忘れられます。

もし自身以外の何かに評価されるなら、 setcheckに割り当てられた名前はクォートしなければいけません。 例えば、もしx, y, zが既にバインドされているなら、 チェックする変数のリストに置くには、

setcheck: ['x, 'y, 'z]$

をタイプしてください。

setcheckリスト上の変数が、例えば、X: 'Xのように、 それ自身に割り当てられた時は、なにも印字されません。

オプション変数: setcheckbreak

デフォルト値: false

setcheckbreaktrueの時、 setcheckリスト上の変数が新しい値を割り当てられた時はいつでも Maximaはブレイクプロンプトを出します。 ブレイクは、割り当てが実行される前に起こります。 この時点で、setvalが変数が割り当てられようとしている値を保持します。 ゆえに、 setvalに割り当てることで、違う値を割り当てることができます。

setchecksetvalも参照してください。

システム変数: setval

setcheckbreakが起こった時、変数が設定されようとしている値を保持します。 ゆえに、 setvalに割り当てることで、違う値を割り当てることができます。

setchecksetcheckbreakも参照してください。

関数: timer (f_1, …, f_n)
関数: timer (all)
関数: timer ()

timerは、 タイミング統計が収集される関数のリストに与えられた関数f_1, …, f_n それぞれを入れます。 timer(f)$ timer(g)$は、リストにfを入れ、その後gを入れます; リストはあるコールから次へ累積されます。

timer(all)は、計測される関数のリストに (グローバル変数functionsで指名されたように) ユーザー定義関数すべてを入れます。

引数なしでは、 timerは計測される関数のリストを返します。

Maximaは、計測される関数のリストに関して、 関数それぞれを実行するのに費やされる時間を記録します。 timer_infoは、タイミング統計を返します。 関数コール毎に経過した平均時間、コール回数、総経過時間を含みます。 untimerは、計測される関数のリストから関数を削除します。

timerは引数をクォートします。 f(x) := x^2$ g:f$ timer(g)$は、fをタイマーリストに入れません。

もしtrace(f)が有効なら、timer(f)は有効ではないです; tracetimerが同時に有効にはできません。

timer_devalueも参照してください。

関数: untimer (f_1, …, f_n)
関数: untimer ()

untimerはタイマーリストから 与えられた関数f_1, …, f_nそれぞれを削除します。

引数なしの時、 untimerは、現在、タイマーリスト上の関数すべてを削除します。

untimer (f)が実行された後、 timer_info() (引数なし)は、 現在タイマーリスト上にない関数についての情報を返しませんけれども、 timer_info (f)は、まだ以前に集計されたタイミング統計を返します。 timer (f)は、 タイミング統計すべてをゼロに再設定し、 fをタイマーリストに再び入れます。

オプション変数: timer_devalue

デフォルト値: false

timer_devaluetrueの時、 Maximaは、計られる関数から 他の計測される関数で費やされた時間を引きます。 そうでなければ、関数それぞれについて報告された時間は、 他の関数で計測される時間を含みます。 計測されない関数で費やされた時間は、総時間から引かれないことに注意してください。

timertimer_infoも参照してください。

関数: timer_info (f_1, ..., f_n)
関数: timer_info ()

与えられた関数f_1, ..., f_n, timer_infoは、 関数それぞれのタイミング情報を含む 行列を返します。 引数なしでは、 timer_infoは、 現在タイマーリスト上の関数すべてについての タイミング情報を返します。 The matrix returned by timer_infoが返す行列は、関数名、 関数コール毎の時間、関数コールの回数、総時間、 gctime を含みます。 gctimeは、元のMacymaの「ガーベッジコレクション時間」を意味しましたが、 今はいつもゼロです。

timer_infoが戻り値を構成するデータは、 get関数によっても得られることができます:

get(f, 'calls);  get(f, 'runtime);  get(f, 'gctime);

timerも参照してください。

関数: trace (f_1, …, f_n)
関数: trace (all)
関数: trace ()

関数 f_1, …, f_nが与えられたとして、 traceは、Maximaに、 それらの関数がコールされたときはいつでも デバッグ情報を印字するよう指示します。 trace(f)$ trace(g)$は、トレースする関数のリストに fを、それからgを入れます; リストは1回のコールから次へ累積します。

trace(all)は、(グローバル変数functionsで指名されたように) ユーザー定義関数すべてをトレースする関数のリストに入れます。

引数なしでは、 traceは、現在とレースする関数すべてのリストを返します。

untrace関数はトレースをディセーブルします。 trace_optionsも参照してください。

traceは引数をクォートします。 例えば、 f(x) := x^2$ g:f$ trace(g)$は、 fをトレースリストに入れません。

関数が再定義された時、 タイマーリストから削除されます。 例えば、 timer(f)$ f(x) := x^2$の後、 関数fはもはやタイマーリストにありません。

もしtimer (f)が有効なら、 trace (f)は有効ではありません; tracetimerは、同じ関数で同時には有効にできません。

関数: trace_options (f, option_1, …, option_n)
関数: trace_options (f)

関数fについてトレースオプションを設定します。 いかなる以前のオプションも破棄されます。 trace_options (f, ...)は、 もし(trace_optionsの前でも後でも). trace (f)もコールされないなら、 有効になりません。

trace_options (f)は、 オプションすべてをデフォルト値に再設定します。

オプションキーワードは以下の通りです:

  • noprint 関数の入り口と出口でメッセージを印字しません。
  • break 関数に入る前と関数を抜けた後、ブレイクポイントを置きます。 breakを参照してください。
  • lisp_print 引数を表示し、Lispオブジェクトとして値を返します。
  • info 関数の入れ口と出口で-> trueを印字します
  • errorcatch エラーをチャッチし、 エラーを知らせるためのオプションに応じて、 関数コールを再試行するか、戻り値を指定します。

トレースオプションは、2つの形式で指定されます。 オプションキーワード単体の存在は、 オプションを無条件に実行します。 (foo: trueか似た形式を指定することでは、 オプションfooは実行されないことに注意してください; キーワードはクォートする必要はないことにも注意してください。) オプションキーワードを述語論理関数で指定することは、 オプションを述語論理上の条件付きにします。

述語論理関数の引数リストは、いつも [level, direction, function, item]です。 ここで、levelは関数の再帰レベルで、 directionenterexitfunctionは、 関数名、 name of the function, and itemは(入るときの)引数リストか(出るときの)戻り値です。

以下は無条件とレースオプションの例です:

(%i1) ff(n) := if equal(n, 0) then 1 else n * ff(n - 1)$

(%i2) trace (ff)$

(%i3) trace_options (ff, lisp_print, break)$

(%i4) ff(3);

以下は述語論理上の条件のbreakオプションを持つ同じ関数です:

(%i5) trace_options (ff, break(pp))$

(%i6) pp (level, direction, function, item) := block (print (item),
    return (function = 'ff and level = 3 and direction = exit))$

(%i7) ff(6);
関数: untrace (f_1, …, f_n)
関数: untrace ()

untraceは、 与えられた関数f_1, …, f_nについて、 trace関数でイネーブルされたトレースをディセーブルします。 引数なしでは、untraceは関数すべてのトレースをディセーブルします。

untraceはトレースをディセーブルした関数のリストを返します。


Next: , Previous:   [Contents][Index]