[インデックス 14341] ファイルの概要
このコミットは、Go言語のランタイムにおけるデータ競合検出機能(Race Detector)にWindowsサポートを追加するものです。これにより、Windows/amd64環境でもgo test -race
コマンドを使用してデータ競合を検出できるようになります。
コミット
commit 1ebf2d85ba02ff7d3f97e52855166174d71666c2
Author: Dmitriy Vyukov <dvyukov@google.com>
Date: Wed Nov 7 23:59:09 2012 +0400
runtime/race: add Windows support
This is copy of https://golang.org/cl/6810080
but sent from another account (dvyukov@gmail.com is not in CONTRIBUTORS).
R=rsc
CC=golang-dev
https://golang.org/cl/6827060
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/1ebf2d85ba02ff7d3f97e52855166174d71666c2
元コミット内容
runtime/race: add Windows support
This is copy of https://golang.org/cl/6810080
but sent from another account (dvyukov@gmail.com is not in CONTRIBUTORS).
R=rsc
CC=golang-dev
https://golang.org/cl/6827060
変更の背景
Go言語のデータ競合検出機能(Race Detector)は、並行処理における潜在的なバグであるデータ競合を特定するための強力なツールです。この機能は、元々Linux/amd64およびDarwin/amd64(macOS)環境でのみサポートされていました。しかし、Go言語が様々なプラットフォームで利用されるようになるにつれて、Windows環境での開発者もデータ競合検出の恩恵を受けたいというニーズが高まりました。
このコミットは、そのニーズに応えるために、GoのRace DetectorがWindows/amd64環境でも動作するように拡張することを目的としています。これにより、Windowsユーザーも開発プロセスにおいてデータ競合を早期に発見し、より堅牢な並行プログラムを構築できるようになります。コミットメッセージにあるように、この変更は既存の変更セット(https://golang.org/cl/6810080
)のコピーであり、別のGo貢献者アカウントから送信されたものです。
前提知識の解説
データ競合 (Data Race)
データ競合とは、複数のゴルーチン(またはスレッド)が同時に同じメモリ位置にアクセスし、そのうち少なくとも1つのアクセスが書き込みであり、かつそれらのアクセスが同期メカニズムによって保護されていない場合に発生するバグです。データ競合は、プログラムの予測不可能な動作、クラッシュ、または誤った結果を引き起こす可能性があります。並行プログラミングにおいて最も発見が困難なバグの一つとされています。
Go Race Detector
Go言語には、データ競合を検出するための組み込みツールである「Race Detector」が提供されています。これは、プログラムの実行中にメモリアクセスを監視し、データ競合のパターンを検出する動的解析ツールです。go test -race
コマンドを使用することで、テスト実行時にRace Detectorを有効にできます。Race Detectorは、コンパイル時に特別なインストゥルメンテーション(計測コードの挿入)を行い、実行時にその計測コードがメモリアクセスを追跡します。競合が検出されると、Race Detectorは詳細なレポート(競合が発生した場所、関連するゴルーチンスタックトレースなど)を出力します。
go test -race
go test -race
は、Goのテストコマンドに-race
フラグを追加することで、Race Detectorを有効にしてテストを実行します。これにより、テストスイートがデータ競合の有無をチェックされ、並行処理のバグを特定するのに役立ちます。
.syso
ファイル
.syso
ファイルは、Windows環境におけるGoのビルドプロセスで使用されるオブジェクトファイルの一種です。これは通常、C/C++で書かれたコードをコンパイルした結果であり、GoプログラムからCGO(C言語との相互運用機能)を通じて呼び出される外部ライブラリやシステムコールをリンクするために使用されます。Race Detectorのような低レベルの機能は、OS固有のAPIや最適化されたアセンブリコードに依存することが多いため、Windows固有の実装が.syso
ファイルとして提供されることがあります。このファイルには、Windows上でRace Detectorが機能するために必要なコンパイル済みバイナリコードが含まれています。
+build
タグ
Goのソースファイルでは、ファイルの先頭に+build
タグを記述することで、そのファイルが特定のビルド条件(OS、アーキテクチャ、タグなど)が満たされた場合にのみコンパイルされるように指定できます。例えば、// +build linux,amd64
は、LinuxかつAMD64アーキテクチャの場合にのみそのファイルがビルドされることを意味します。このコミットでは、race.go
ファイルにrace,windows,amd64
が追加されており、これはRace Detectorが有効で、かつWindows/amd64環境の場合にこのファイルがビルドされることを示しています。
技術的詳細
このコミットの技術的な核心は、GoのRace DetectorがWindows/amd64環境で動作するために必要な変更をGoツールチェーンとランタイムに加えることです。
-
go
コマンドの-race
フラグのサポート拡張:src/cmd/go/build.go
ファイルは、go
コマンドのビルドロジックを定義しています。以前は、-race
フラグはLinux/amd64とDarwin/amd64でのみサポートされていました。このコミットでは、goos != "windows"
のチェックが追加され、Windows/amd64もサポート対象として認識されるようになります。これにより、go test -race
コマンドがWindows環境でエラーなく実行できるようになります。 -
Race Detectorのビルド条件の更新:
src/pkg/runtime/race/race.go
ファイルは、Race DetectorのGo言語側のインターフェースと共通ロジックを定義しています。このファイルのビルドタグ// +build race,linux,amd64 race,darwin,amd64
にrace,windows,amd64
が追加されました。これは、Race Detectorが有効(race
タグ)で、かつWindows/amd64環境の場合に、このrace.go
ファイルがコンパイル対象に含まれることを意味します。これにより、Windows固有のRace Detectorの実装がGoランタイムに適切にリンクされるようになります。 -
Windows固有のRace Detectorバイナリの追加:
src/pkg/runtime/race/race_windows_amd64.syso
という新しいバイナリファイルが追加されました。これは、Windows/amd64環境でRace Detectorが機能するために必要な、コンパイル済みの低レベルなC/C++コードまたはアセンブリコードを含むオブジェクトファイルです。Goのビルドシステムは、この.syso
ファイルをGoのランタイムにリンクすることで、Windows固有のシステムコールやAPIを利用したデータ競合検出ロジックを統合します。 -
Windowsバッチスクリプトの更新:
src/run.bat
は、Goプロジェクトのテストやビルドを実行するためのWindowsバッチスクリプトです。このスクリプトに、Windows環境でのRace Detectorのテストケースが追加されました。具体的には、%GOHOSTOS%-%GOOS%-%GOARCH%-%CGO_ENABLED%
変数をチェックして、Windows/amd64環境でCGOが有効な場合にのみRace Detectorのテスト(go test -race -i flag
とgo test -race -short flag
)を実行するロジックが追加されています。これにより、Windows環境でのRace Detectorの機能が自動テストによって検証されるようになります。
これらの変更により、GoのビルドシステムはWindows/amd64環境で-race
フラグが指定された場合に、適切なRace Detectorのコンポーネントをコンパイル・リンクし、データ競合検出機能を提供できるようになります。
コアとなるコードの変更箇所
このコミットにおける主要なコード変更は以下のファイルに集中しています。
-
src/cmd/go/build.go
--- a/src/cmd/go/build.go +++ b/src/cmd/go/build.go @@ -1840,8 +1840,8 @@ func raceInit() { if !buildRace { return } - if goarch != "amd64" || goos != "linux" && goos != "darwin" { - fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64 and darwin/amd64\\n", flag.Args()[0]) + if goarch != "amd64" || goos != "linux" && goos != "darwin" && goos != "windows" { + fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, darwin/amd64 and windows/amd64\\n", flag.Args()[0]) os.Exit(2) } buildGcflags = append(buildGcflags, "-b")
-
src/pkg/runtime/race/race.go
--- a/src/pkg/runtime/race/race.go +++ b/src/pkg/runtime/race/race.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build race,linux,amd64 race,darwin,amd64 +// +build race,linux,amd64 race,darwin,amd64 race,windows,amd64 // Package race provides low-level facilities for data race detection. package race
-
src/pkg/runtime/race/race_windows_amd64.syso
--- /dev/null +++ b/src/pkg/runtime/race/race_windows_amd64.syso Binary files /dev/null and b/src/pkg/runtime/race/race_windows_amd64.syso differ
(新規追加されたバイナリファイル)
-
src/run.bat
--- a/src/run.bat +++ b/src/run.bat @@ -52,6 +52,15 @@ go test sync -short -timeout=120s -cpu=10 if errorlevel 1 goto fail echo. +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 errorlevel 1 goto fail +echo. +:norace + echo # ..\misc\dashboard\builder ..\misc\goplay go build ..\misc\dashboard\builder ..\misc\goplay if errorlevel 1 goto fail
コアとなるコードの解説
src/cmd/go/build.go
の変更
この変更は、go
コマンドが-race
フラグを処理する際のOSとアーキテクチャのチェックを更新しています。
元のコードでは、goarch != "amd64" || goos != "linux" && goos != "darwin"
という条件で、AMD64以外のアーキテクチャ、またはLinuxとDarwin以外のOSの場合にエラーメッセージを出力し、プログラムを終了していました。
変更後、条件はgoarch != "amd64" || goos != "linux" && goos != "darwin" && goos != "windows"
となりました。これにより、goos
がwindows
である場合も、エラーチェックを通過するようになります。つまり、Windows/amd64環境がRace Detectorのサポート対象として正式に認識されるようになりました。エラーメッセージも、Windows/amd64がサポート対象に含まれるように更新されています。
src/pkg/runtime/race/race.go
の変更
このファイルはGoのRace DetectorのGo言語側の部分を定義しており、ファイルの先頭にある+build
タグは、このファイルがどの環境でコンパイルされるべきかを指定します。
元のタグ// +build race,linux,amd64 race,darwin,amd64
は、Race Detectorが有効(race
タグが存在)で、かつLinux/amd64またはDarwin/amd64の場合にこのファイルをビルドすることを示していました。
変更後、race,windows,amd64
が追加されました。これにより、Race Detectorが有効で、かつWindows/amd64環境の場合にもこのrace.go
ファイルがコンパイル対象に含まれるようになり、Windows固有のRace Detectorの実装がGoランタイムに統合される道が開かれました。
src/pkg/runtime/race/race_windows_amd64.syso
の追加
このファイルは新規に追加されたバイナリファイルです。.syso
拡張子は、Windowsシステムオブジェクトファイルを示し、通常はC/C++で書かれたコンパイル済みのコードを含みます。Goのビルドシステムは、CGOを介してこれらのファイルをGoプログラムにリンクできます。
このファイルは、Windows/amd64環境でRace Detectorが機能するために必要な、低レベルなOS固有のロジック(例えば、メモリ監視、スレッド同期プリミティブのフックなど)を実装したコンパイル済みバイナリであると推測されます。GoのRace Detectorは、GoogleのThreadSanitizerプロジェクトをベースにしており、その実装にはOS固有の低レベルなコードが含まれるため、このようなバイナリファイルが必要となります。
src/run.bat
の変更
src/run.bat
は、Goプロジェクトのテストスイートを実行するためのWindowsバッチスクリプトです。この変更は、Windows環境でRace Detectorのテストが実行されるようにするためのものです。
追加されたif not "%GOHOSTOS%-%GOOS%-%GOARCH%-%CGO_ENABLED%" == "windows-windows-amd64-1" goto norace
という行は、現在の環境変数がWindows/amd64でCGOが有効な場合(CGO_ENABLED=1
)にのみ、その後のRace Detectorのテストを実行するように条件分岐しています。
その後のgo test -race -i flag
とgo test -race -short flag
は、Race Detectorを有効にしてflag
パッケージのテストを実行するコマンドです。-i
フラグは依存関係をインストールし、-short
フラグは短時間で実行できるテストのみを実行します。これにより、Windows環境でのRace Detectorの基本的な機能が、自動テストによって検証されるようになりました。
これらの変更が連携することで、GoのRace DetectorはWindows/amd64環境で完全に機能するようになり、開発者はこの強力なツールをより広範なプラットフォームで利用できるようになりました。
関連リンク
- 元の変更セット (CL): https://golang.org/cl/6810080
- このコミットに対応する変更セット (CL): https://golang.org/cl/6827060
参考にした情報源リンク
- Go Data Race Detector: https://go.dev/blog/race-detector
- Go Command Documentation (
go test
): https://go.dev/cmd/go/#hdr-Test_packages - Go Build Constraints (
+build
tags): https://go.dev/cmd/go/#hdr-Build_constraints - Go and Cgo: https://go.dev/blog/cgo
- ThreadSanitizer (Race Detectorの基盤): https://clang.llvm.org/docs/ThreadSanitizer.html
- What is a .syso file in Go?: https://stackoverflow.com/questions/24700000/what-is-a-syso-file-in-go (Web検索で得られた情報)