日曜日, 12月 27, 2015

LLDBでGoのデバッグをする その2 test編

その1ではgo buildしたLLDBでデバッグしてみましたが、その2ではgo testでのdebugの仕方です。

今回のデバッグ対象として以下のようなプログラム(main.go)とそのテスト(main_test.go)を書きました。

package main

import "fmt"

func RectArea(w, h int) int {
    return w * h
}
package main

import "testing"

func TestRectArea(t *testing.T) {
    s := RectArea(6, 8)
    if s != 48 {
        t.Error("error")
    }
}

testをビルドする

go test には -c というオプションがあり、これを使うとtestのバイナリをビルドできます。これと -gcflags を組み合わせてデバッグ可能なtestバイナリを作ります。

# -o は出力結果のファイル名を指定するオプション
$ go test -c -gcflags '-N -l' -o test
# 実行するとgo testと同じ結果が得られる
$ ./test
PASS

デバッグする

後は、前回同様lldbに、このtestバイナリを渡すだけです。

$ lldb test 
(lldb) target create "test"
Current executable set to 'test' (x86_64).
(lldb)

せっかくなのでプログラム本体とテスト両方にブレイクポイントを置いてみます。

(lldb) target create "test"
Current executable set to 'test' (x86_64).
(lldb) b main.go:4
Breakpoint 1: where = test`_/Users/kmtr/misc/c.RectArea + 9 at main.go:6, address = 0x000000000007dc09
(lldb) b main_test.go:7
Breakpoint 2: where = test`_/Users/kmtr/misc/c.TestRectArea + 58 at main_test.go:7, address = 0x000000000007dc5a
(lldb)

後は run するだけです。
main.go側で止まったところで、変数を確認。

   3    func RectArea(w, h int) int {
   4        return w * h
   5    }
(lldb) fr v
(long) w = 6
(long) h = 8
(long) ~r2 = 0
(lldb)

c で継続して、次はmain_test.goで止まるので、こちらでも変数を確認。
そして c で終了させます。

   4    
   5    func TestRectArea(t *testing.T) {
   6        s := RectArea(6, 8)
-> 7        if s != 48 {
   8            t.Error("error")
   9        }
   10   }
(lldb) fr v
(long) s = 48
(testing.T *) t = 0x000000c82009c000
(lldb) c
Process 25022 resuming
PASS
Process 25022 exited with status = 0 (0x00000000) 
(lldb)  

まとめ

-c オプションでtestバイナリを作るのがポイントで、後は前回と同じですね。

また続くかもしれない。

0 件のコメント: