[ < ] | [ > ] |  | [ << ] | [上] | [ >> ] |  |  |  |  | [冒頭] | [目次] | [見出し] | [ ? ]

# 38. Debugging

[ < ] | [ > ] |  | [ << ] | [上] | [ >> ] |  |  |  |  | [冒頭] | [目次] | [見出し] | [ ? ]

## 38.1 Source Level Debugging

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

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

Maximaプロンプトで、 `:br`コマンドでブレイクポイントが設定できます。 デバッガー内では、ユーザーは、 `:n` ("next")コマンドを使って１度に１行進むことができます。 `: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に評価ような、そのファイルウィンドウで利用可能な追加のコマンドがあります。

Categories: Debugging

[ < ] | [ > ] |  | [ << ] | [上] | [ >> ] |  |  |  |  | [冒頭] | [目次] | [見出し] | [ ? ]

## 38.2 Keyword Commands

キーワードコマンドは Maxima式として解釈 (interpret)されない特殊キーワードです。 キーワードコマンドはブレイクプロンプトではできませんが、 Maximaプロンプトやデバッガープロンプトで入力できます。 キーワードコマンドはコロン '`:`'で始まります。 例えば Lisp形を評価するには `: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プロンプトに戻ります。

Categories: Debugging

[ < ] | [ > ] |  | [ << ] | [上] | [ >> ] |  |  |  |  | [冒頭] | [目次] | [見出し] | [ ? ]

## 38.3 Functions and Variables for Debugging

オプション変数: debugmode

  デフォルト値: `false`

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

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

  Categories: Debugging · Global flags

オプション変数: refcheck

  デフォルト値: `false`

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

  Categories: Evaluation · Console interaction · Global flags

オプション変数: setcheck

  デフォルト値: `false`

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

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

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

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

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

  をタイプしてください。

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

  Categories: Console interaction · Global flags

オプション変数: setcheckbreak

  デフォルト値: `false`

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

  `setcheck`と `setval`も参照してください。

  Categories: Console interaction · Global flags

システム変数: setval

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

  `setcheck`と `setcheckbreak`も参照してください。

  Categories: Console interaction · Global variables

関数: 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)`は有効ではないです; `trace`と `timer`が同時に有効にはできません。

  `timer_devalue`も参照してください。

  Categories: Debugging

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

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

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

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

  Categories: Debugging

オプション変数: timer_devalue

  デフォルト値: `false`

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

  `timer`と `timer_info`も参照してください。

  Categories: Debugging · Global flags

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

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

  `timer_info`が戻り値を構成するデータは、 `get`関数でも得ることができます:

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

  `timer`も参照してください。

  Categories: Debugging

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

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

  `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)`は有効ではありません; `trace`と `timer`は同じ関数で同時には有効にできません。

  Categories: Debugging

関数: 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` エラーをチャッチし、 エラーを知らせるためのオプションに応じて、 関数コールを再試行するか、戻り値を指定します。

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

  述語論理関数の引数リストは、いつも `[level, direction, function, item]`です。 ここで `level`は関数の再帰レベルで、 `direction`は `enter`か `exit`を取り、 `function`は関数名であり、 `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);

  Categories: Debugging

関数: untrace
`untrace` (f_1, …, f_n)
`untrace` ()

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

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

  Categories: Debugging

[ << ] | [ >> ] |  |  |  |  |  | [冒頭] | [目次] | [見出し] | [ ? ]

この文書は市川 雄二によって1月, 7 2015にtexi2html 1.76を用いて生成されました。