Go言語のOS X上でのGDBデバッグ環境構築

Go言語は gdbでのデバッグがサポートされている のだが、OS X でそれを使おうとしたらいろいろ罠にはまったのでここに記しておく。

(このエントリ執筆時の手元の環境は OS X 10.9(.0) Mavericks + Xcode 5.0.1)

罠一覧

  1. OS X 付属のgdbが古い
  2. Xcode 5.0.1のclangだとgdbのビルドがこける
  3. ビルドするgdbはpython2にリンクさせないとGo付属のruntime-gdb.pyが動かない[1]
  4. ビルドしたgdbにコード署名をしないと他プロセスをアタッチできない

OS X 付属のgdbが古い

Goのコードをgdbでデバッグするには、gdb 7.1以上が必要ということだが、OS X (Xcode?) 付属のgdbは古くて使えない。 手元のバージョンは GNU gdb 6.3.50-20050815 (Apple version gdb-1820) となっていた。

なのでgdbを自前でビルドする必要がある。

Xcode 5.0.1のclangだとgdbのビルドがこける

gdbを自前でビルドしようとするも、

error: adding 'char' to a string does not append to the string [-Werror,-Wstring-plus-int]

とか言われてしまってビルドがこける。

これは CFLAGS に -Wno-string-plus-int を含めてやればスルーしてくれる。

ビルドするgdbはpython2にリンクさせないとGo付属のruntime-gdb.pyが動かない

Goにはruntime-gdb.pyというgdb用のスクリプトが付属していて、これを使うことでgoroutineの一覧や、変数の中身などを良い感じに表示したりということができるようになる。 詳しくは Debugging Go Code with GDB 参照。

ただ、このスクリプトはPython3だと動かない。

Mavericks付属のPythonは、まだ2.7系なのでそれをそのまま使っている人は大丈夫だろう。 自分はpyenvで3系を入れているので、この罠にはまった。

pyenvの場合はビルド時に、

pyenv shell 2.7.5

などとして一時的に2.7系に切り替えてやればOKだ。

ビルドしたgdbにコード署名をしないと他プロセスをアタッチできない

OS Xのセキュリティ対策でコード署名されていないプログラムは他プロセスにアクセスすることができない。

これはgdbのwikiに Building GDB for Darwin として詳しく説明されていて、解決方法も書かれているから、ここの通りにすれば良い。

手順

自分のやった手順を一応まとめておく。

まずはgdbの新規インストール。homebrewの位置に入るようにする。

# pythonを2.7に切り替えておく
pyenv shell 2.7.5

# gdb最新版をとってくる
wget http://ftp.gnu.org/gnu/gdb/gdb-7.6.1.tar.gz
tar xvf gdb-7.6.1.tar.gz
cd gdb-7.6.1

# -Wno-string-plus-int をつけてビルド
./configure --prefix=$(brew --prefix)/Cellar/gdb/7.6.1 CFLAGS="-g -O2 -Wno-string-plus-int"
make
make install

# 他のbrewコマンドと同じように使えるようにしておく
brew link gdb

次にコード署名用の自己証明書を作成。

  1. キーチェーンアクセスを開いて、メニューから 「キーチェーンアクセス」→「証明書アシスタント」→「証明書を作成…」を選ぶ。
  2. 名前に「gdb-cert」、固有名のタイプは「自己署名ルート」、証明書のタイプは「コード署名」、デフォルトを無効化にチェックを入れ、作成をクリック
  3. 「証明書の場所を指定」という項目になるまで「続ける」を選ぶ
  4. 場所の指定は「システム」を選択して作成
  5. できた証明書[2]を右クリックして「情報を見る」を選び、「信頼」の項目内の「この証明書を信頼するとき」というところを「常に信頼」とする

作った証明書でgdbをコード署名

codesign -s gdb-cert $(brew --prefix)/Cellar/gdb/7.6.1/bin/gdb

これでようやく[3]、OS X上でもgdbでGoのコードのデバッグができるようになった。