Goブログ
Goコードのデバッグ(状況報告)
デバッグに関しては、変数を検査するためのいくつかの戦略的な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では読み取れません。標準のOS X GDBとの互換性を確保するためにパッチを提供いただければ幸いです。ただし、それが修正されるまでは、OS Xで使用する場合は、GDB 7.xをダウンロード、ビルド、インストールする必要があります。ソースコードはhttp://sourceware.org/gdb/download/にあります。OS Xの特性上、`chgrp procmod`と`chmod 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で使用できます。