The Go Blog

Go コードのデバッグ (現状報告)

Luuk van Dijk
2010年11月2日

デバッグに関して言えば、変数を検査するための戦略的なprint文や、スタックトレースを取得するための適切なpanicに勝るものはありません。しかし、忍耐力やソースコードが不足している場合もあり、そのような場合には優れたデバッガが非常に貴重です。そのため、過去数回のリリースで、Goのgcリンカ (6l, 8l) におけるGNUデバッガであるGDBのサポートを改善してきました。

最新リリース (2010-11-02) では、6lおよび8lリンカがELF (Linux, FreeBSD) またはMach-O (Mac OS X) バイナリを書き込む際にDWARF3デバッグ情報を出力します。DWARFコードは、以下のことを可能にするのに十分な情報を含んでいます

  • GDBバージョン7.xでGoプログラムをロードする
  • すべてのGo、C、およびアセンブリのソースファイルを行ごとに一覧表示する (Goランタイムの一部はCとアセンブリで記述されています)
  • 行ごとにブレークポイントを設定し、コードをステップ実行する
  • スタックトレースを表示し、スタックフレームを検査する
  • ほとんどの変数のアドレスを見つけ、その内容を表示する

まだいくつかの不便な点があります

  • 出力されるDWARFコードは、Mac OS Xに付属するGDBバージョン6.xでは読み取れません。DWARF出力を標準のOS X GDBと互換性のあるものにするためのパッチは大歓迎ですが、それが修正されるまでは、OS XでGDB 7.xを使用するには、ダウンロード、ビルド、およびインストールする必要があります。ソースはhttp://sourceware.org/gdb/download/で見つけることができます。OS Xの特殊性により、chgrp procmodchmod g+sを使用してバイナリをローカルファイルシステムにインストールする必要があります。
  • 名前はパッケージ名で修飾され、GDBはGoパッケージを理解しないため、各項目を完全な名前で参照する必要があります。たとえば、パッケージmainの変数vは、単一引用符で囲んで'main.v'として参照する必要があります。この結果、変数名や関数名のタブ補完は機能しません。
  • 字句スコープ情報はやや不明瞭です。同じ名前の変数が複数ある場合、n番目のインスタンスには「#n」の形式の接尾辞が付きます。これを修正する予定ですが、コンパイラとリンカ間で交換されるデータにいくつかの変更が必要になります。
  • スライスおよび文字列変数は、ランタイムライブラリ内の基盤となる構造として表現されます。それらは{data = 0x2aaaaab3e320, len = 1, cap = 1}のようになります。スライスの場合、要素を検査するにはデータポインタを逆参照する必要があります。

まだ機能しない点

  • チャネル、関数、インターフェース、マップ変数は検査できません。
  • Go変数のみが型情報で注釈付けされます。ランタイムのC変数は注釈付けされません。
  • WindowsおよびARMバイナリにはDWARFデバッグ情報が含まれていないため、GDBで検査できません。

今後数か月で、コンパイラとリンカの変更、またはGDBへのPython拡張機能の使用のいずれかによって、これらの問題に対処する予定です。それまでの間、Goプログラマーがこの有名なデバッグツールにアクセスしやすくなることで恩恵を受けることを願っています。

追伸:DWARF情報はGDB以外のツールでも読み取ることができます。たとえば、Linuxではsysprofシステム全体プロファイラで使用できます。

次の記事:Go:今日の1年前
前の記事:Real Go Projects: SmartTwitterとweb.go
ブログインデックス