導入まで手間がかかったのでメモ。
コマンドラインツールに含まれるgdb
はちょっと古い (GNU gdb 6.3.50-20050815 (Apple version gdb-1824)
)ので
Goのデバッグに使えません。また、導入したgdbでプロセスのデバッグをするためには署名を入れる必要があります。
さらに、環境変数を適切にセットした上で正しいファイル構成でコンパイルする必要があります。
Goが利用できるgdbを導入する
brewを用いました。
brew install homebrew/dupes/gdb
これだけだと、Gatekeeperによってデバッグプロセスの実行を禁止されてしまいます。
Unable to find Mach task port for process-id 84034: (os/kern) failure (0x5). (please check gdb is codesigned - see taskgated(8))
これをやめるにはこのgdbに署名を付けてしまえばよいです。
手順は次の通りです。
Keychain Accessを起動してCreate Certificateを選択。
いろいろ変更する。
- 「Name」を「gdb-cert」にする
- 「Certificate Type」を「Code Signing」にする
- 「Let me override defautls」にチェック
Continueしまくってから、Specify a Location For The Certificateでは「Keychain」を「System」にする。そして「Create」をクリック。
キーチェイン変更でパスワードを求められる。
無事追加された。
Keychain Accessでgdb-certを見つける。KeychainsをSystemにして、CategoryをMy Certificatesにすると見つかりやすい。
ダブルクリックで詳細を見て、Trustを展開。Code SigningをAlways Trustにする。
codesign -s gdb-cert /usr/local/Cellar/gdb/7.7/bin/gdb
sudo killall taskgated
なお、署名の手順などの詳細は次のページを参照してください。
あとは、このgdbに、パスを通したり、エイリアスやリンクを張ればよいでしょう。
alias ggdb=/usr/local/Cellar/gdb/7.7/bin/gdb
Goでgdbデバッグできるようにする
こちらもbrewを用いました。
brew install go
そして、環境変数GOROOT
をセットしておきます。これは設定ファイルに書いてもよいでしょう。
export GOROOT=/usr/local/Cellar/go/1.2.1/libexec
gdb起動時に、Goのランタイムサポート用のスクリプト$GOROOT/src/pkg/runtime/runtime-gdb.py
を読みに行くのでGOROOT
を正しくセットする必要があるのです。
続いての環境変数GOPATH
は、結論から言うと、ターミナル上でGoのプロジェクトのルートディレクトリで、export GOPATH=`pwd`
としたほうがよいみたいです。
なぜなら、gdbは「GOPATH environment variable」
のようなファイル構成があると思っていて、$GOPATH/src
以下からソースファイルを捜すためです。
なので、例えば、パッケージfoo
のソースは、$GOPATH/src/foo
なんかに置いておくと見つけてくれます。
環境変数を設定して、ファイルを正しい場所に置いたら、あとはコンパイルするだけです。例えば、パッケージfooをコンパイルするには次のようにします。
$ go build -gcflags "-N -l" foo
-gcflags "-N -l"
は関数のインライン化や変数のレジスタ化をやめさせるためのオプションです。
これで生成されたバイナリをデバッグするには次のようにします。
$ ggdb ./foo -d .
gdbの利用例
ブレークポイントはfoo.go:12
とかmain.fibonacci
とか指定します。
$ cat src/main/foo.go package main import "fmt" func fibonacci(n int) int { if n == 0 { return 0 } if n == 1 { return 1 } return fibonacci(n-1) + fibonacci(n-2) } func main() { fmt.Println("fibonacci") fmt.Println(fibonacci(20)) } $ go build -gcflags "-N -l" main $ ggdb ./main -d . GNU gdb (GDB) 7.7 Copyright (C) 2014 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-apple-darwin13.1.0". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ./main...done. Loading Go Runtime support. (gdb) b main.fibonacci Breakpoint 1 at 0x2000: file /Users/safx/src/golang/src/main/foo.go, line 5. (gdb) r Starting program: /Users/safx/src/golang/main fibonacci [New Thread 0x160f of process 92283] [New Thread 0x1803 of process 92283] [New Thread 0x1903 of process 92283] Breakpoint 1, main.fibonacci (n=20, ~anon1=1) at /Users/safx/src/golang/src/main/foo.go:5 5 func fibonacci(n int) int { (gdb) bt #0 main.fibonacci (n=20, ~anon1=1) at /Users/safx/src/golang/src/main/foo.go:5 #1 0x0000000000002167 in main.main () at /Users/safx/src/golang/src/main/foo.go:17 (gdb) c Continuing. Breakpoint 1, main.fibonacci (n=19, ~anon1=10) at /Users/safx/src/golang/src/main/foo.go:5 5 func fibonacci(n int) int { (gdb) clear Deleted breakpoint 1 (gdb) c Continuing. 6765 [Inferior 1 (process 92631) exited normally]
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。