その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バイナリを作るのがポイントで、後は前回と同じですね。
また続くかもしれない。