[インデックス 15519] ファイルの概要
このコミットは、Go言語のテストスクリプト run.bat
において、データ競合検出器(Race Detector)のテストを一時的に無効化する変更を加えています。これは、特定のバグ(Go issue 4948)が原因でテストが失敗するための一時的な回避策です。
コミット
commit 211589a9edf433019e8ad5937afe3bb98ebebc35
Author: Alex Brainman <alex.brainman@gmail.com>
Date: Fri Mar 1 14:19:56 2013 +1100
run.bat: disable race detector test
R=golang-dev, dave
CC=golang-dev
https://golang.org/cl/7439048
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/211589a9edf433019e8ad5937afe3bb98ebebc35
元コミット内容
run.bat: disable race detector test
R=golang-dev, dave
CC=golang-dev
https://golang.org/cl/7439048
変更の背景
このコミットの背景には、Go言語のデータ競合検出器(Race Detector)に関連する既知のバグが存在していました。コミットメッセージに記載されている http://code.google.com/p/go/issues/detail?id=4948
は、このバグを指しています。
Go言語の開発プロセスでは、継続的インテグレーション(CI)の一環として、様々なテストが自動的に実行されます。その中には、データ競合検出器を有効にした状態でのテストも含まれています。しかし、当時の特定の環境や条件下で、このデータ競合検出器のテストがバグにより正しく動作せず、失敗してしまう問題が発生していました。
テストの失敗は、CIパイプラインをブロックし、他の健全な変更の統合を妨げる可能性があります。そのため、このコミットは、根本的なバグが修正されるまでの間、一時的に問題のあるデータ競合検出器のテストをスキップすることで、CIパイプラインの健全性を維持することを目的としています。これは、開発の進行を妨げないための実用的な措置と言えます。
前提知識の解説
Go言語のデータ競合検出器 (Race Detector)
Go言語のデータ競合検出器は、並行処理における「データ競合(Data Race)」を検出するための強力なツールです。データ競合は、複数のゴルーチン(Goの軽量スレッド)が同時に同じメモリ領域にアクセスし、そのうち少なくとも1つが書き込み操作であり、かつそれらのアクセスが適切な同期メカニズムによって保護されていない場合に発生します。データ競合は、プログラムの予測不能な動作、クラッシュ、または誤った結果を引き起こす可能性があり、デバッグが非常に困難な種類のバグです。
Goのデータ競合検出器は、コンパイル時にメモリアクセスを計測(instrumentation)することで機能します。プログラムの実行中に、Goランタイムは共有変数への非同期アクセスを監視し、競合状態が検出されると警告を出力します。この警告には、競合が発生したゴルーチン、コードの行番号、および関連するスタックトレースなど、詳細な情報が含まれます。
データ競合検出器は、go test -race
や go run -race
、go build -race
のように、go
コマンドに -race
フラグを付けて使用します。これにより、テスト実行時、プログラム実行時、またはバイナリビルド時にデータ競合の検出が有効になります。
ただし、データ競合検出器を有効にすると、実行時のオーバーヘッドが大きくなります。メモリ使用量が5〜10倍に増加し、実行時間が2〜20倍になることがあります。そのため、通常は開発およびテスト段階で使用され、本番環境では無効にされます。また、データ競合検出器は実行時に発生する競合のみを検出するため、テストカバレッジが重要になります。静的解析のように、実行されないコードパスの競合を検出することはできません。
run.bat
スクリプト
run.bat
は、Windows環境でGo言語のテストやビルドプロセスを実行するためのバッチスクリプトです。Go言語のプロジェクトでは、クロスプラットフォーム対応のために、シェルスクリプト(Linux/macOS向け)とバッチスクリプト(Windows向け)の両方が用意されていることがよくあります。このスクリプトは、Goのソースコードリポジトリのルートにある src
ディレクトリに配置されており、Goのテストスイート全体を実行する役割を担っています。
スクリプト内では、go test
コマンドが様々なフラグや引数と共に実行され、Goの標準ライブラリやツール群の機能が正しく動作するかどうかを検証します。データ競合検出器のテストも、このスクリプトの一部として実行されるように設定されていました。
Go Issue 4948
コミットメッセージに記載されている http://code.google.com/p/go/issues/detail?id=4948
は、Go言語の公式イシュートラッカー(当時はGoogle Codeでホストされていた)における特定のバグ報告を指します。Web検索の結果によると、このイシューはGo 1.13とApache Thriftの依存関係におけるチェックサム不一致の問題に関連している可能性が示唆されていますが、コミットが2013年であることから、これは別のイシューである可能性が高いです。
2013年当時のGo issue 4948は、データ競合検出器のテストが特定の条件下で誤って失敗する、またはハングアップするような問題であったと推測されます。このような問題は、テストインフラストラクチャの安定性を損ない、開発者が実際のバグとテストインフラのバグを区別するのを困難にします。そのため、一時的な回避策としてテストをスキップする判断が下されました。
技術的詳細
このコミットは、Windows環境におけるGo言語のテストスクリプト src/run.bat
に変更を加えています。具体的には、データ競合検出器のテストセクションに、テストをスキップするためのロジックを追加しています。
run.bat
スクリプトは、Goのテストを実行する際に、環境変数 GOHOSTOS
, GOOS
, GOARCH
, CGO_ENABLED
の値に基づいて、特定のテストセクションを実行するかどうかを判断しています。データ競合検出器のテストは、通常 windows-windows-amd64-1
の組み合わせ(つまり、Windows上でWindows AMD64向けにCGOが有効な場合)に限定されていました。これは、データ競合検出器がCGO(C言語との相互運用機能)を必要とし、特定のプラットフォームでのみサポートされていたためです。
変更前は、この条件が満たされると、go test -race
コマンドが実行され、データ競合検出器を有効にした状態でテストが実行されていました。しかし、Go issue 4948で報告されたバグにより、このテストが不安定であったため、コミットでは以下の2行が追加されました。
-
echo # skipping test due to bug (http://code.google.com/p/go/issues/detail?id=4948).
- この行は、テストがスキップされる理由をコンソールに出力するためのコメントです。開発者やCIシステムが、なぜこのテストが実行されないのかを理解できるようにするためのものです。
-
goto norace
- この行は、バッチスクリプトの制御フローを変更するコマンドです。
goto
は指定されたラベル(この場合はnorace
)に処理をジャンプさせます。これにより、go test -race
コマンドを含む後続のデータ競合検出器のテストコードが実行されずにスキップされます。norace
ラベルは、データ競合検出器のテストセクションの終わり、またはそのセクションを完全にスキップするためのジャンプ先として、スクリプトの別の場所に定義されていると推測されます。
- この行は、バッチスクリプトの制御フローを変更するコマンドです。
この変更により、Go issue 4948が修正されるまでの間、Windows AMD64環境でのデータ競合検出器のテストは実行されなくなり、CIパイプラインの安定性が確保されました。これは、バグの根本的な修正ではなく、一時的な回避策であり、バグが修正された後にはこの変更が元に戻されることが期待されます。
コアとなるコードの変更箇所
--- a/src/run.bat
+++ b/src/run.bat
@@ -54,6 +54,8 @@ echo.
if not "%GOHOSTOS%-%GOOS%-%GOARCH%-%CGO_ENABLED%" == "windows-windows-amd64-1" goto norace
echo # Testing race detector.
+echo # skipping test due to bug (http://code.google.com/p/go/issues/detail?id=4948).
+goto norace
go test -race -i flag
if errorlevel 1 goto fail
go test -race -short flag
コアとなるコードの解説
変更は src/run.bat
ファイルの54行目付近にあります。
元のコードでは、以下の条件文でデータ競合検出器のテストを実行するかどうかを判断していました。
if not "%GOHOSTOS%-%GOOS%-%GOARCH%-%CGO_ENABLED%" == "windows-windows-amd64-1" goto norace
echo # Testing race detector.
go test -race -i flag
if errorlevel 1 goto fail
go test -race -short flag
この条件文 if not "%GOHOSTOS%-%GOOS%-%GOARCH%-%CGO_ENABLED%" == "windows-windows-amd64-1" goto norace
は、「もし現在の環境が windows-windows-amd64-1
でないならば、norace
ラベルにジャンプしてデータ競合検出器のテストをスキップする」という意味です。つまり、このテストはWindows AMD64環境でCGOが有効な場合にのみ実行されるように設計されていました。
このコミットによって、この条件文が満たされ、データ競合検出器のテストが実行されるべきパスに入った直後に、以下の2行が追加されました。
echo # skipping test due to bug (http://code.google.com/p/go/issues/detail?id=4948).
goto norace
-
echo # skipping test due to bug (http://code.google.com/p/go/issues/detail?id=4948).
- これは単なるコメント行であり、
echo
コマンドによって標準出力にメッセージが表示されます。このメッセージは、なぜデータ競合検出器のテストがスキップされるのかを明確に示しています。
- これは単なるコメント行であり、
-
goto norace
- この行が変更の核心です。
goto
コマンドは、バッチスクリプトの実行フローを強制的にnorace
というラベルに移動させます。これにより、このgoto
コマンドの直後に続くgo test -race -i flag
やgo test -race -short flag
といった実際のデータ競合検出器のテストコマンドは実行されなくなります。
- この行が変更の核心です。
結果として、この変更は、特定のバグが修正されるまで、Windows AMD64環境におけるデータ競合検出器のテストを完全にバイパスする役割を果たします。これは、テストスイート全体の実行を妨げる不安定なテストを一時的に無効化するための、シンプルかつ効果的な方法です。
関連リンク
- Go issue 4948 (当時のGoogle Codeのイシュートラッカー):
http://code.google.com/p/go/issues/detail?id=4948
(現在のGoイシュートラッカーでは、古いイシューはGitHubに移行されているか、参照が変更されている可能性があります。Web検索結果では、Go 1.13とApache Thriftの関連イシューが示唆されていますが、コミット日付からすると別のイシューである可能性が高いです。) - Go CL 7439048:
https://golang.org/cl/7439048
(GoのコードレビューシステムであるGerritの変更リストへのリンク)
参考にした情報源リンク
- Go言語のデータ競合検出器に関する公式ドキュメント: https://go.dev/doc/articles/race_detector
- Go言語のデータ競合検出器に関する解説記事 (例):
- Web検索結果: "Go issue 4948", "Go race detector" (これらの検索結果から、データ競合検出器の概要と、イシュー番号の一般的な意味合いを参考にしました。)