debug



B. Gauche でのデバッグ

プログラムが、思いどおり動かないとき、原因を探る必要があります。 それぞれの手続き(プロシージャ)が「意図したとおり動いているか」を知る 必要があります。

B.1. リーダマクロ #?=expr

これは、C 言語をつかったプログラミングでは、「printf デバッグ」などと 言われることのある古典的なデバッグ手法のためのマクロです。 #?=expr は (debug-print expr) のように読まれ、これは、expr を 評価してその値を返しますが、評価の直前に評価する式を、 評価直後にその値を、印字します。

以下は、リファレンスマニュアルにある例です。

gosh> #?=(+ 2 3)
#?="(stdin)":1:(+ 2 3)
#?-    5
5
gosh> #?=(begin (print "foo") (values 'a 'b 'c))
#?="(stdin)":2:(begin (print "foo") (values 'a 'b 'c))
foo
#?-    a
#?+    b
#?+    c
a
b
c
gosh> (define (fact n)
        (if (zero? n)
            1
            (* n #?=(fact (- n 1)))))
fact
gosh> (fact 5)
#?="(stdin)":6:(fact (- n 1))
#?="(stdin)":6:(fact (- n 1))
#?="(stdin)":6:(fact (- n 1))
#?="(stdin)":6:(fact (- n 1))
#?="(stdin)":6:(fact (- n 1))
#?-    1
#?-    1
#?-    2
#?-    6
#?-    24
120

B.2. ggc.debug.trace

skim さんの ggc ライブラリに ggc.debug.trace というモジュールがあります。これには、trace という マクロとuntrace というマクロが定義されています。trace を使うと、手続き の呼出しをその引数の値とともに追跡することができます。untrace は trace を解除するマクロです。

gosh> (use ggc.debug.trace)
(#<module ggc.debug.trace> #<module gauche.interactive>)
gosh> (define (tarai x y z)
        (if (<= x y)
            y
            (tarai (tarai (- x 1) y z)
                   (tarai (- y 1) z x)
                   (tarai (- z 1) x y))))
tarai
gosh> (trace tarai)
#<closure 0x806b500(x)>
gosh> (tarai 4 2 1)
0:(tarai 4 2 1)
1:  (tarai 3 2 1)
2:    (tarai 2 2 1)
      ->2
2:    (tarai 1 1 3)
      ->1
2:    (tarai 0 3 2)
      ->3
2:    (tarai 2 1 3)
3:      (tarai 1 1 3)
        ->1
3:      (tarai 0 3 2)
        ->3
3:      (tarai 2 2 1)
        ->2
3:      (tarai 1 3 2)
        ->3
      ->3
    ->3
1:  (tarai 1 1 4)
    ->1
1:  (tarai 0 4 2)
    ->4
1:  (tarai 3 1 4)
2:    (tarai 2 1 4)
3:      (tarai 1 1 4)
        ->1
3:      (tarai 0 4 2)
        ->4
3:      (tarai 3 2 1)
4:        (tarai 2 2 1)
          ->2
4:        (tarai 1 1 3)
          ->1
4:        (tarai 0 3 2)
          ->3
4:        (tarai 2 1 3)
5:          (tarai 1 1 3)
            ->1
5:          (tarai 0 3 2)
            ->3
5:          (tarai 2 2 1)
            ->2
5:          (tarai 1 3 2)
            ->3
          ->3
        ->3
3:      (tarai 1 4 3)
        ->4
      ->4
2:    (tarai 0 4 3)
      ->4
2:    (tarai 3 3 1)
      ->3
2:    (tarai 4 4 3)
      ->4
    ->4
  ->4
; trace: tarai has been called 29 times.
4
gosh> (untrace)
()
gosh> (tarai 4 2 1)
4

Powered by Kahua