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

[インデックス 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 -racego run -racego 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. goosgoarch

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つの側面で変更を加えています。

  1. go コマンドのヘルプメッセージとバリデーションの更新: src/cmd/go/build.gosrc/cmd/go/doc.goは、go build -raceコマンドのヘルプメッセージと、-raceフラグがサポートされているOS/アーキテクチャの組み合わせをチェックするロジックを含んでいます。これらのファイルにFreeBSD/amd64が追加され、ユーザーがFreeBSD上で-raceフラグを使用しようとした際に、誤ったエラーメッセージが表示されないように修正されました。

  2. Race Detectorのビルドタグの更新: src/pkg/runtime/race/race.goは、Go Race Detectorのコアロジックを含むパッケージです。このファイルのビルドタグにrace,freebsd,amd64が追加されました。これにより、FreeBSD/amd64環境で-raceフラグを付けてGoプログラムをビルドする際に、このrace.goファイルがコンパイル対象に含まれるようになります。

  3. 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 buildgo 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環境に対応し、データ競合検出機能が利用可能になります。

関連リンク

参考にした情報源リンク