[インデックス 19585] ファイルの概要
このコミットは、Go言語のデータ競合検出機能(Race Detector)がFreeBSD/amd64環境をサポートするように拡張するものです。これにより、FreeBSD上で動作するGoプログラムにおいても、並行処理におけるデータ競合の問題を検出できるようになります。
コミット
runtime/race: support freebsd
All tests pass except one test in regexp package.
LGTM=iant
R=golang-codereviews, iant, dave
CC=golang-codereviews
https://golang.org/cl/107270043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/f1f37f93d08ca24dc9769dc448b6f96bc3667aaf
元コミット内容
commit f1f37f93d08ca24dc9769dc448b6f96bc3667aaf
Author: Dmitriy Vyukov <dvyukov@google.com>
Date: Fri Jun 20 20:20:56 2014 -0400
runtime/race: support freebsd
All tests pass except one test in regexp package.
LGTM=iant
R=golang-codereviews, iant, dave
CC=golang-codereviews
https://golang.org/cl/107270043
---
src/cmd/go/build.go | 6 +++---\n src/cmd/go/doc.go | 2 +-\n src/pkg/runtime/race/race.go | 2 +-\n src/pkg/runtime/race/race_freebsd_amd64.syso | Bin 0 -> 261096 bytes
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
index 3645f1c2d5..1dc13cf068 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -64,7 +64,7 @@ and test commands:
The default is the number of CPUs available.
-race
enable data race detection.
- Supported only on linux/amd64, darwin/amd64 and windows/amd64.
+ Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
-v
print the names of packages as they are compiled.
-work
@@ -2556,8 +2556,8 @@ func raceInit() {
if !buildRace {
return
}
- 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])
+ if goarch != "amd64" || goos != "linux" && goos != "freebsd" && goos != "darwin" && goos != "windows" {
+ fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64\\n", flag.Args()[0])
os.Exit(2)
}
buildGcflags = append(buildGcflags, "-race")
diff --git a/src/cmd/go/doc.go b/src/cmd/go/doc.go
index 9840804ce7..52737f9f8b 100644
--- a/src/cmd/go/doc.go
+++ b/src/cmd/go/doc.go
@@ -82,7 +82,7 @@ and test commands:
The default is the number of CPUs available.
-race
enable data race detection.
- Supported only on linux/amd64, darwin/amd64 and windows/amd64.
+ Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
-v
print the names of packages as they are compiled.
-work
diff --git a/src/pkg/runtime/race/race.go b/src/pkg/runtime/race/race.go
index e53cacf4a0..3c297e84b2 100644
--- 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 race,windows,amd64
+// +build race,linux,amd64 race,freebsd,amd64 race,darwin,amd64 race,windows,amd64
package race
diff --git a/src/pkg/runtime/race/race_freebsd_amd64.syso b/src/pkg/runtime/race/race_freebsd_amd64.syso
new file mode 100644
index 0000000000..b25d868f48
Binary files /dev/null and b/src/pkg/runtime/race/race_freebsd_amd64.syso differ
変更の背景
Go言語のデータ競合検出機能(Race Detector)は、並行処理における共有メモリへの非同期アクセスによって発生するデータ競合を特定するための強力なツールです。この機能は、Goプログラムの信頼性とデバッグ効率を大幅に向上させます。しかし、この機能は特定のオペレーティングシステム(OS)とアーキテクチャの組み合わせに依存して実装されています。
このコミットが作成された時点では、GoのRace DetectorはLinux/amd64、macOS (darwin)/amd64、およびWindows/amd64の各環境でのみサポートされていました。FreeBSDは、サーバーや組み込みシステムで広く利用されているUNIX系OSであり、Go言語のユーザーベースも存在します。FreeBSD環境でGoプログラムを開発・運用するユーザーにとって、データ競合検出機能が利用できないことは、デバッグや品質保証の面で大きな制約となっていました。
このコミットの背景には、Go言語のRace Detectorの適用範囲を広げ、より多くのプラットフォームで開発者が並行処理のバグを効率的に特定できるようにするという目的があります。FreeBSD/amd64環境へのサポート追加は、Goエコシステムの成熟と、より広範なプラットフォームへの対応の一環として行われました。
前提知識の解説
1. データ競合 (Data Race)
データ競合とは、複数のゴルーチン(Goにおける軽量スレッド)が同時に同じメモリ位置にアクセスし、そのうち少なくとも1つのアクセスが書き込みであり、かつそれらのアクセスが同期メカニズムによって保護されていない場合に発生するバグです。データ競合は、プログラムの予測不能な動作、クラッシュ、または誤った結果を引き起こす可能性があり、デバッグが非常に困難です。
2. Go Race Detector
Go Race Detectorは、Goプログラムの実行中にデータ競合を動的に検出するツールです。go build -race
、go run -race
、go test -race
などのコマンドで有効にできます。このツールは、プログラムの実行パスを監視し、共有メモリへのアクセスパターンを追跡することで、潜在的な競合を特定します。内部的には、Googleが開発したThreadSanitizer (TSan)という動的解析ツールをベースにしています。TSanは、コンパイル時にコードに計測(instrumentation)を挿入し、実行時にメモリアクセスを監視することで競合を検出します。
3. go build
コマンドとビルドタグ
go build
コマンドはGoソースコードをコンパイルして実行可能ファイルを生成します。-race
フラグを付けることで、Race Detectorを有効にしたビルドが行われます。
Goのビルドシステムには「ビルドタグ(build tags)」という機能があります。これは、ソースファイルの上部に// +build tag1,tag2
のようなコメントを記述することで、特定の条件が満たされた場合にのみそのファイルをコンパイル対象に含めるメカニズムです。例えば、// +build linux,amd64
と書かれたファイルは、OSがLinuxでアーキテクチャがamd64の場合にのみビルドされます。Race Detector関連のコードは、race
タグと特定のOS/アーキテクチャの組み合わせでビルドされるように設定されています。
4. goos
と goarch
goos
(Go Operating System) と goarch
(Go Architecture) は、GoのクロスコンパイルにおいてターゲットとなるOSとCPUアーキテクチャを指定するための環境変数です。例えば、GOOS=linux GOARCH=amd64 go build
とすることで、Linux/amd64環境で動作するバイナリを現在の環境でビルドできます。Race Detectorのサポートは、これらの組み合わせに依存します。
5. .syso
ファイル
Goのビルドプロセスでは、.syso
という拡張子を持つファイルが特別な意味を持ちます。これらは「システムオブジェクトファイル」と呼ばれ、Goコンパイラによって直接処理されるのではなく、Goツールチェーンが呼び出すCコンパイラ(通常はGCCやClang)によってコンパイルされたオブジェクトファイルです。GoプログラムにC/C++で書かれたライブラリをリンクする場合や、OS固有の低レベルな機能を利用する場合に用いられます。Race Detectorの実装では、ThreadSanitizerのランタイムライブラリがOS固有のC/C++コードで書かれており、これが.syso
ファイルとしてGoのビルドに組み込まれます。
技術的詳細
このコミットは、FreeBSD/amd64環境でGo Race Detectorを有効にするために、主に以下の3つの側面で変更を加えています。
-
go
コマンドのヘルプメッセージとバリデーションの更新:src/cmd/go/build.go
とsrc/cmd/go/doc.go
は、go build -race
コマンドのヘルプメッセージと、-race
フラグがサポートされているOS/アーキテクチャの組み合わせをチェックするロジックを含んでいます。これらのファイルにFreeBSD/amd64が追加され、ユーザーがFreeBSD上で-race
フラグを使用しようとした際に、誤ったエラーメッセージが表示されないように修正されました。 -
Race Detectorのビルドタグの更新:
src/pkg/runtime/race/race.go
は、Go Race Detectorのコアロジックを含むパッケージです。このファイルのビルドタグにrace,freebsd,amd64
が追加されました。これにより、FreeBSD/amd64環境で-race
フラグを付けてGoプログラムをビルドする際に、このrace.go
ファイルがコンパイル対象に含まれるようになります。 -
FreeBSD固有のRace Detectorランタイムライブラリの追加:
src/pkg/runtime/race/race_freebsd_amd64.syso
という新しいバイナリファイルが追加されました。これは、FreeBSD/amd64環境に特化したThreadSanitizerのランタイムライブラリのオブジェクトファイルです。GoのRace Detectorは、OS固有のシステムコールやメモリ管理のフックを必要とするため、各OS/アーキテクチャの組み合わせに対して専用のランタイムライブラリが必要です。この.syso
ファイルがGoのビルドプロセスに組み込まれることで、FreeBSD上でRace Detectorが正しく機能するための基盤が提供されます。
これらの変更により、go build -race
コマンドがFreeBSD/amd64環境で実行された際に、FreeBSD固有のRace Detectorランタイムがリンクされ、データ競合検出機能が利用可能になります。
コミットメッセージにある「All tests pass except one test in regexp package.」という記述は、FreeBSD上でのRace Detectorの基本的な機能は検証済みであるものの、regexp
パッケージの特定のテストでまだ問題が残っていることを示唆しています。これは、Race Detectorが低レベルなシステム動作に深く関わるため、完全に安定させるには追加の調整が必要であることを示しています。
コアとなるコードの変更箇所
src/cmd/go/build.go
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -64,7 +64,7 @@ and test commands:
The default is the number of CPUs available.
-race
enable data race detection.
- Supported only on linux/amd64, darwin/amd64 and windows/amd64.
+ Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
-v
print the names of packages as they are compiled.
-work
@@ -2556,8 +2556,8 @@ func raceInit() {
if !buildRace {
return
}
- 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])
+ if goarch != "amd64" || goos != "linux" && goos != "freebsd" && goos != "darwin" && goos != "windows" {
+ fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64\\n", flag.Args()[0])
os.Exit(2)
}
buildGcflags = append(buildGcflags, "-race")
src/cmd/go/doc.go
--- a/src/cmd/go/doc.go
+++ b/src/cmd/go/doc.go
@@ -82,7 +82,7 @@ and test commands:
The default is the number of CPUs available.
-race
enable data race detection.
- Supported only on linux/amd64, darwin/amd64 and windows/amd64.
+ Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
-v
print the names of packages as they are compiled.
-work
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 race,windows,amd64
+// +build race,linux,amd64 race,freebsd,amd64 race,darwin,amd64 race,windows,amd64
package race
src/pkg/runtime/race/race_freebsd_amd64.syso
このファイルは新規追加されたバイナリファイルです。
コアとなるコードの解説
src/cmd/go/build.go
および src/cmd/go/doc.go
の変更
これらのファイルは、go
コマンドのビルドおよびドキュメント生成に関連するロジックを含んでいます。
- ヘルプメッセージの更新:
-race
フラグの説明文において、サポートされるプラットフォームのリストにfreebsd/amd64
が追加されました。これは、ユーザーがgo help build
やgo help test
を実行した際に、FreeBSDが正式にサポートされていることを明示的に伝えるためです。 - プラットフォームチェックの更新:
raceInit()
関数内の条件分岐が変更されました。以前はgoarch != "amd64" || goos != "linux" && goos != "darwin" && goos != "windows"
という条件で、サポートされていないプラットフォームで-race
フラグが使用された場合にエラーメッセージを出力し、プログラムを終了していました。この条件にgoos != "freebsd"
が追加され、FreeBSD/amd64がサポート対象として認識されるようになりました。これにより、FreeBSD上で-race
フラグを使用してもエラーで終了せず、ビルドが続行されるようになります。
これらの変更は、ユーザーインターフェースとコマンドラインツールの動作をFreeBSDサポートに合わせて調整するものです。
src/pkg/runtime/race/race.go
の変更
このファイルは、Go Race Detectorのランタイムパッケージの一部です。
- ビルドタグの追加: ファイルの先頭にあるビルドタグの行に
race,freebsd,amd64
が追加されました。 元のタグ:// +build race,linux,amd64 race,darwin,amd64 race,windows,amd64
変更後のタグ:// +build race,linux,amd64 race,freebsd,amd64 race,darwin,amd64 race,windows,amd64
この変更により、Goコンパイラは、ターゲットOSがFreeBSDでアーキテクチャがamd64であり、かつ-race
フラグが指定されている場合に、このrace.go
ファイルをコンパイル対象に含めるようになります。これは、Race DetectorのGo言語側のロジックがFreeBSD環境でも有効になるために不可欠な変更です。
src/pkg/runtime/race/race_freebsd_amd64.syso
の追加
このファイルは、FreeBSD/amd64環境に特化したThreadSanitizerのランタイムライブラリのオブジェクトファイルです。
- システムオブジェクトファイルの組み込み: Goのビルドシステムは、
.syso
ファイルを自動的にリンク対象に含めます。このバイナリファイルは、FreeBSDのシステムコールやメモリ管理の特性に合わせてコンパイルされたThreadSanitizerの低レベルな実装を含んでいます。Race Detectorは、メモリの読み書きを監視し、同期プリミティブの操作を追跡するために、OSカーネルとのインタラクションや特定のシステムAPIへのフックが必要です。この.syso
ファイルが提供されることで、FreeBSD上でThreadSanitizerが正しく動作し、Goプログラムのデータ競合を検出できるようになります。
これらの変更が組み合わさることで、Goのビルドツール、ランタイム、およびRace DetectorのコアロジックがFreeBSD/amd64環境に対応し、データ競合検出機能が利用可能になります。
関連リンク
- Go CL 107270043: https://golang.org/cl/107270043
- Go Race Detector Documentation: https://go.dev/doc/articles/race_detector (一般的なGo Race Detectorに関する情報)
参考にした情報源リンク
- Go Race Detector Documentation: https://go.dev/doc/articles/race_detector
- Go Command Documentation (
go build
): https://go.dev/cmd/go/#hdr-Build_and_test_Go_packages - Go Build Tags: https://go.dev/pkg/go/build/#hdr-Build_Constraints
- ThreadSanitizer (TSan) Overview: https://clang.llvm.org/docs/ThreadSanitizer.html
- Go
syso
files (Stack Overflow discussion): https://stackoverflow.com/questions/24094500/what-is-the-purpose-of-syso-files-in-go (一般的な.syso
ファイルの役割に関する情報)