Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 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ツールチェーンとランタイムに加えることです。

  1. goコマンドの-raceフラグのサポート拡張: src/cmd/go/build.goファイルは、goコマンドのビルドロジックを定義しています。以前は、-raceフラグはLinux/amd64とDarwin/amd64でのみサポートされていました。このコミットでは、goos != "windows"のチェックが追加され、Windows/amd64もサポート対象として認識されるようになります。これにより、go test -raceコマンドがWindows環境でエラーなく実行できるようになります。

  2. Race Detectorのビルド条件の更新: src/pkg/runtime/race/race.goファイルは、Race DetectorのGo言語側のインターフェースと共通ロジックを定義しています。このファイルのビルドタグ// +build race,linux,amd64 race,darwin,amd64race,windows,amd64が追加されました。これは、Race Detectorが有効(raceタグ)で、かつWindows/amd64環境の場合に、このrace.goファイルがコンパイル対象に含まれることを意味します。これにより、Windows固有のRace Detectorの実装がGoランタイムに適切にリンクされるようになります。

  3. Windows固有のRace Detectorバイナリの追加: src/pkg/runtime/race/race_windows_amd64.sysoという新しいバイナリファイルが追加されました。これは、Windows/amd64環境でRace Detectorが機能するために必要な、コンパイル済みの低レベルなC/C++コードまたはアセンブリコードを含むオブジェクトファイルです。Goのビルドシステムは、この.sysoファイルをGoのランタイムにリンクすることで、Windows固有のシステムコールやAPIを利用したデータ競合検出ロジックを統合します。

  4. Windowsバッチスクリプトの更新: src/run.batは、Goプロジェクトのテストやビルドを実行するためのWindowsバッチスクリプトです。このスクリプトに、Windows環境でのRace Detectorのテストケースが追加されました。具体的には、%GOHOSTOS%-%GOOS%-%GOARCH%-%CGO_ENABLED%変数をチェックして、Windows/amd64環境でCGOが有効な場合にのみRace Detectorのテスト(go test -race -i flaggo test -race -short flag)を実行するロジックが追加されています。これにより、Windows環境でのRace Detectorの機能が自動テストによって検証されるようになります。

これらの変更により、GoのビルドシステムはWindows/amd64環境で-raceフラグが指定された場合に、適切なRace Detectorのコンポーネントをコンパイル・リンクし、データ競合検出機能を提供できるようになります。

コアとなるコードの変更箇所

このコミットにおける主要なコード変更は以下のファイルに集中しています。

  1. 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")
    
  2. 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
    
  3. 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
    

    (新規追加されたバイナリファイル)

  4. 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"となりました。これにより、gooswindowsである場合も、エラーチェックを通過するようになります。つまり、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 flaggo test -race -short flagは、Race Detectorを有効にしてflagパッケージのテストを実行するコマンドです。-iフラグは依存関係をインストールし、-shortフラグは短時間で実行できるテストのみを実行します。これにより、Windows環境でのRace Detectorの基本的な機能が、自動テストによって検証されるようになりました。

これらの変更が連携することで、GoのRace DetectorはWindows/amd64環境で完全に機能するようになり、開発者はこの強力なツールをより広範なプラットフォームで利用できるようになりました。

関連リンク

参考にした情報源リンク