vscode goでテストコードのブレークポイントにかからない問題

ブレークポイントが効かない不思議な体験
ある日、Go のデバッグ環境で予期せぬ問題に直面しました。VS Code と Go 拡張を利用してテストを実行していたのですが、特定のテストだけブレークポイントが全く反応しないという現象が起きたのです。実行ログを見ると、テストは PASS となっていたものの、デバッガが全く介入せず、すぐにプロセスが終了してしまいました。
手探りのデバッグ作業
最初は、コンパイル時の最適化やインライン展開の影響を疑い、ビルド時にデバッグ用のフラグを追加することを検討しました。具体的には、以下のフラグです。
-gcflags=all=-N -l
これにより、最適化とインライン展開が無効化され、ソースコードと生成されたバイナリの対応関係が保たれるため、ブレークポイントの位置情報が正確になるとされています(参考:Go のデバッグ手法)。Makefile に専用のデバッグ用タスクを作成し、デバッグ環境でこのフラグを付与してビルドするように設定しました。
しかし、これらの対策を講じてもなお、問題は解消されませんでした。

意外な落とし穴―シンボリックリンクの影響
- 不具合の原因がわからないままVS Code の Go 拡張に搭載されたテストエクスプローラを使っていたのですが、そこで同じテストコードが2種類表示されていることに気づきました。
- 一方は期待通りの場所から読み込まれているのに対し、もう一方は異なるパスに表示されていました。この不自然な挙動が、解決の契機となりました。
そういえば、プロジェクトのソースコードがシンボリックリンク経由で管理していたことを思い出しました。具体的には、以下のような設定になっていました。
/home/USERNAME/git/PROJECT_NAME -> /home/USERNAME/.go/src/github.com/GITHUB_ACCOUNT/PROJECT_NAME/
この状態では、実体は /home/USERNAME/.go/src/github.com/GITHUB_ACCOUNT/PROJECT_NAME/
に存在しているものの、作業ディレクトリとしては /home/USERNAME/git/PROJECT_NAME
を参照していました。その結果、VS Code のテストエクスプローラでは同一テストが異なるパスとして認識され、デバッガが正しいソースコードの位置情報を取得できず、ブレークポイントが無視される原因となっていたようだった。
シンボリックリンクを削除して解決しました。