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

[インデックス 11861] ファイルの概要

このコミットは、Go言語のランタイムとシステムコールに関する修正であり、特にFreeBSD-386アーキテクチャでのビルド問題を解決することを目的としています。具体的には、src/pkg/runtime/signal_freebsd_386.c から不要なシグナル名取得関数を削除し、src/pkg/syscall/zerrors_freebsd_386.go におけるシグナル定数の定義方法を修正しています。これにより、FreeBSD-386環境でのGoプログラムのコンパイルおよび実行時の安定性が向上しました。

コミット

commit 2d53d227f67fd38b9e4cd0d21f6f29c101b808da
Author: Andrew Gerrand <adg@golang.org>
Date:   Tue Feb 14 10:04:59 2012 +1100

    runtime, syscall: fix freebsd-386 build
    
    R=rsc
    CC=golang-dev
    https://golang.org/cl/5659045

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/2d53d227f67fd38b9e4cd0d21f6f29c101b808da

元コミット内容

runtime, syscall: fix freebsd-386 build

R=rsc
CC=golang-dev
https://golang.org/cl/5659045

変更の背景

このコミットは、2012年頃に報告されたFreeBSD-386環境におけるGoのビルド問題、特に「runtime: garbage collection crash in freebsd/386 runtime running on freebsd/amd64」というGitHub Issue #2675に関連するものです。この問題は、FreeBSD/386上でGoのパッケージやコマンドをビルドする際に、ランタイムがFreeBSD/amd64システム上で動作している場合にセグメンテーション違反(Segmentation fault: 11)が発生するというものでした。

Go言語はクロスコンパイルをサポートしており、異なるアーキテクチャやOS向けにバイナリを生成できます。しかし、FreeBSD-386環境での特定のシグナル処理やシステムコール定義に不整合があったため、ビルドプロセスが正常に完了せず、実行時にクラッシュする問題が発生していました。このコミットは、これらの不整合を解消し、FreeBSD-386環境でのGoの安定した動作を保証するために行われました。

前提知識の解説

  • Goランタイム (runtime): Go言語のプログラムが実行される際に必要となる、ガベージコレクション、スケジューリング、システムコールインターフェースなどの低レベルな機能を提供する部分です。OSやアーキテクチャに依存する部分が多く含まれます。
  • システムコール (syscall): オペレーティングシステムが提供するサービス(ファイルI/O、ネットワーク通信、プロセス管理など)をプログラムから利用するためのインターフェースです。Go言語では、syscallパッケージを通じてこれらの機能にアクセスします。
  • FreeBSD-386: FreeBSDはUNIX系のオペレーティングシステムであり、-386はIntel 80386プロセッサアーキテクチャ(32ビット)を指します。Go言語は様々なOSとアーキテクチャの組み合わせをサポートしており、それぞれの環境に合わせた低レベルな実装が必要です。
  • シグナル (Signal): オペレーティングシステムがプロセスに対して送信する非同期の通知メカニズムです。プログラムの異常終了(セグメンテーション違反など)、外部からの割り込み(Ctrl+Cなど)、タイマーイベントなど、様々な状況で発生します。プログラムはシグナルを捕捉し、特定の処理を実行することができます。
  • src/pkg/runtime/signal_freebsd_386.c: GoランタイムにおけるFreeBSD-386アーキテクチャ向けのシグナル処理に関するC言語のソースファイルです。低レベルなシグナルハンドリングやレジスタダンプなどの機能が含まれます。
  • src/pkg/syscall/zerrors_freebsd_386.go: GoのsyscallパッケージにおけるFreeBSD-386アーキテクチャ向けの定数定義ファイルです。このファイルは通常、Goのツールによって自動生成され、OS固有のエラーコード、シグナル番号、その他のシステムコール関連の定数が含まれます。ファイル名のzは、Goのビルドシステムにおいて、このファイルが最後にコンパイルされることを示す慣例です。

技術的詳細

このコミットの技術的な詳細は、主にFreeBSD-386環境におけるシグナル定義の整合性と、シグナル名を取得するメカニズムの変更にあります。

  1. runtime·signame 関数の削除: src/pkg/runtime/signal_freebsd_386.c から runtime·signame 関数が削除されました。この関数は、整数値のシグナル番号を受け取り、対応するシグナル名を文字列として返す役割を担っていました。この関数が削除された背景には、Goのランタイムがシグナル名をC言語のコードから直接取得する必要がなくなった、あるいはよりGoらしい方法でシグナル名を取得するメカニズムが導入されたことが考えられます。C言語とGo言語間の文字列のやり取りは、メモリ管理や型変換の点で複雑になることがあり、Go側で管理する方が効率的であると判断された可能性があります。

  2. syscall/zerrors_freebsd_386.go におけるシグナル定数の再定義とSignal型の導入: src/pkg/syscall/zerrors_freebsd_386.go では、既存のシグナル定数(例: SIGABRT, SIGALRMなど)が一度削除され、その後、Signal型にキャストされた形で再定義されています。

    • 変更前: シグナル定数は単なるconstとして定義されていました。
    • 変更後: const (ブロック内で、SIGABRT = Signal(0x6)のように、明示的にSignal型にキャストされています。 この変更は、Goの型システムをより厳密に適用し、シグナル番号が単なる整数ではなく、特定の意味を持つSignal型であることを明確にする意図があります。これにより、型安全性が向上し、誤った型の値がシグナル番号として使用されることを防ぐことができます。 また、NOTE_で始まる定数群(kqueueイベント通知に関連するもの)が追加されています。これは、FreeBSDのkqueueシステムが提供するイベントフィルタリングのフラグであり、ファイルシステムイベントやプロセス状態の変化などを監視するために使用されます。これらの定数が追加されたのは、GoのsyscallパッケージがFreeBSDのkqueue機能をより完全にサポートするため、または既存の定義に不足があったためと考えられます。
  3. signals テーブルの追加: src/pkg/syscall/zerrors_freebsd_386.go に、signalsというstring型の配列が追加されました。この配列は、シグナル番号をインデックスとして、対応するシグナル名の文字列を格納しています。これは、runtime/signal_freebsd_386.c から削除された runtime·signame 関数の機能をGo言語側で再実装したものです。Goのsyscallパッケージ内でシグナル名を管理することで、Cgoを介した呼び出しのオーバーヘッドを削減し、Goのランタイムとシステムコール層の間の依存関係をより明確にすることができます。

これらの変更は、FreeBSD-386環境におけるGoのシグナル処理の正確性を高め、ビルド時のセグメンテーション違反のような問題を解決するために不可欠でした。特に、シグナル定数の型安全性の向上と、シグナル名取得メカニズムのGo言語側への移行は、Goのクロスプラットフォーム対応と内部構造の改善に寄与しています。

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

src/pkg/runtime/signal_freebsd_386.c

--- a/src/pkg/runtime/signal_freebsd_386.c
+++ b/src/pkg/runtime/signal_freebsd_386.c
@@ -36,14 +36,6 @@ runtime·dumpregs(Mcontext *r)
 	runtime·printf("gs      %x\n", r->mc_gs);
 }
 
-String
-runtime·signame(int32 sig)
-{
-	if(sig < 0 || sig >= NSIG)
-		return runtime·emptystring;
-	return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name);
-}
-
 void
 runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
 {

src/pkg/syscall/zerrors_freebsd_386.go

--- a/src/pkg/syscall/zerrors_freebsd_386.go
+++ b/src/pkg/syscall/zerrors_freebsd_386.go
@@ -887,6 +887,29 @@ const (
 	NET_RT_IFLIST                     = 0x3
 	NET_RT_IFMALIST                   = 0x4
 	NET_RT_MAXID                      = 0x5
+	NOTE_ATTRIB                       = 0x8
+	NOTE_CHILD                        = 0x4
+	NOTE_DELETE                       = 0x1
+	NOTE_EXEC                         = 0x20000000
+	NOTE_EXIT                         = 0x80000000
+	NOTE_EXTEND                       = 0x4
+	NOTE_FFAND                        = 0x40000000
+	NOTE_FFCOPY                       = 0xc0000000
+	NOTE_FFCTRLMASK                   = 0xc0000000
+	NOTE_FFLAGSMASK                   = 0xffffff
+	NOTE_FFNOP                        = 0x0
+	NOTE_FFOR                         = 0x80000000
+	NOTE_FORK                         = 0x40000000
+	NOTE_LINK                         = 0x10
+	NOTE_LOWAT                        = 0x1
+	NOTE_PCTRLMASK                    = 0xf0000000
+	NOTE_PDATAMASK                    = 0xfffff
+	NOTE_RENAME                       = 0x20
+	NOTE_REVOKE                       = 0x40
+	NOTE_TRACK                        = 0x1
+	NOTE_TRACKERR                     = 0x2
+	NOTE_TRIGGER                      = 0x1000000
+	NOTE_WRITE                        = 0x2
 	O_ACCMODE                         = 0x3
 	O_APPEND                          = 0x8
 	O_ASYNC                           = 0x40
@@ -995,40 +1018,6 @@ const (
 	SHUT_RD                           = 0x0
 	SHUT_RDWR                         = 0x2
 	SHUT_WR                           = 0x1
-	SIGABRT                           = 0x6
-	SIGALRM                           = 0xe
-	SIGBUS                            = 0xa
-	SIGCHLD                           = 0x14
-	SIGCONT                           = 0x13
-	SIGEMT                            = 0x7
-	SIGFPE                            = 0x8
-	SIGHUP                            = 0x1
-	SIGILL                            = 0x4
-	SIGINFO                           = 0x1d
-	SIGINT                            = 0x2
-	SIGIO                             = 0x17
-	SIGIOT                            = 0x6
-	SIGKILL                           = 0x9
-	SIGLWP                            = 0x20
-	SIGPIPE                           = 0xd
-	SIGPROF                           = 0x1b
-	SIGQUIT                           = 0x3
-	SIGSEGV                           = 0xb
-	SIGSTOP                           = 0x11
-	SIGSYS                            = 0xc
-	SIGTERM                           = 0xf
-	SIGTHR                            = 0x20
-	SIGTRAP                           = 0x5
-	SIGTSTP                           = 0x12
-	SIGTTIN                           = 0x15
-	SIGTTOU                           = 0x16
-	SIGURG                            = 0x10
-	SIGUSR1                           = 0x1e
-	SIGUSR2                           = 0x1f
-	SIGVTALRM                         = 0x1a
-	SIGWINCH                          = 0x1c
-	SIGXCPU                           = 0x18
-	SIGXFSZ                           = 0x19
 	SIOCADDMULTI                      = 0x80206931
 	SIOCADDRT                         = 0x8030720a
 	SIOCAIFADDR                       = 0x8040691a
@@ -1323,6 +1312,44 @@ const (
 	EXDEV           = Errno(0x12)
 )
 
+// Signals
+const (
+	SIGABRT   = Signal(0x6)
+	SIGALRM   = Signal(0xe)
+	SIGBUS    = Signal(0xa)
+	SIGCHLD   = Signal(0x14)
+	SIGCONT   = Signal(0x13)
+	SIGEMT    = Signal(0x7)
+	SIGFPE    = Signal(0x8)
+	SIGHUP    = Signal(0x1)
+	SIGILL    = Signal(0x4)
+	SIGINFO   = Signal(0x1d)
+	SIGINT    = Signal(0x2)
+	SIGIO     = Signal(0x17)
+	SIGIOT    = Signal(0x6)
+	SIGKILL   = Signal(0x9)
+	SIGLWP    = Signal(0x20)
+	SIGPIPE   = Signal(0xd)
+	SIGPROF   = Signal(0x1b)
+	SIGQUIT   = Signal(0x3)
+	SIGSEGV   = Signal(0xb)
+	SIGSTOP   = Signal(0x11)
+	SIGSYS    = Signal(0xc)
+	SIGTERM   = Signal(0xf)
+	SIGTHR    = Signal(0x20)
+	SIGTRAP   = Signal(0x5)
+	SIGTSTP   = Signal(0x12)
+	SIGTTIN   = Signal(0x15)
+	SIGTTOU   = Signal(0x16)
+	SIGURG    = Signal(0x10)
+	SIGUSR1   = Signal(0x1e)
+	SIGUSR2   = Signal(0x1f)
+	SIGVTALRM = Signal(0x1a)
+	SIGWINCH  = Signal(0x1c)
+	SIGXCPU   = Signal(0x18)
+	SIGXFSZ   = Signal(0x19)
+)
+
 // Error table
 var errors = [...]string{
 	1:  "operation not permitted",
@@ -1419,3 +1446,39 @@ var errors = [...]string{
 	92: "protocol error",
 	93: "capabilities insufficient",
 }
+
+// Signal table
+var signals = [...]string{
+	1:  "hangup",
+	2:  "interrupt",
+	3:  "quit",
+	4:  "illegal instruction",
+	5:  "trace/BPT trap",
+	6:  "abort trap",
+	7:  "EMT trap",
+	8:  "floating point exception",
+	9:  "killed",
+	10: "bus error",
+	11: "segmentation fault",
+	12: "bad system call",
+	13: "broken pipe",
+	14: "alarm clock",
+	15: "terminated",
+	16: "urgent I/O condition",
+	17: "suspended (signal)",
+	18: "suspended",
+	19: "continued",
+	20: "child exited",
+	21: "stopped (tty input)",
+	22: "stopped (tty output)",
+	23: "I/O possible",
+	24: "cputime limit exceeded",
+	25: "filesize limit exceeded",
+	26: "virtual timer expired",
+	27: "profiling timer expired",
+	28: "window size changes",
+	29: "information request",
+	30: "user defined signal 1",
+	31: "user defined signal 2",
+	32: "unknown signal",
+}

コアとなるコードの解説

src/pkg/runtime/signal_freebsd_386.c の変更

  • runtime·signame 関数の削除: この関数は、C言語で実装されたGoランタイムの一部であり、シグナル番号に対応するシグナル名を返す役割を担っていました。この関数の削除は、シグナル名の取得ロジックがGo言語側のsyscallパッケージに移行されたことを意味します。これにより、Cgoを介したGoとC間の呼び出しの複雑さが軽減され、Goのランタイムのコードベースがよりクリーンになります。

src/pkg/syscall/zerrors_freebsd_386.go の変更

  • NOTE_ 定数の追加: FreeBSDのkqueueシステムで使用されるイベント通知フラグが追加されました。これらは、ファイルシステムイベント(NOTE_DELETE, NOTE_WRITE, NOTE_RENAMEなど)やプロセスイベント(NOTE_CHILD, NOTE_FORK, NOTE_EXEC, NOTE_EXITなど)を監視するために使用されます。これらの定数の追加により、GoのsyscallパッケージがFreeBSDの高度なイベント通知機能をより完全にサポートできるようになりました。
  • シグナル定数の再定義とSignal型の導入: 以前は単なる整数定数として定義されていたシグナル(SIGABRTなど)が、Signalという新しい型に明示的にキャストされる形で再定義されました。これは、Goの型システムを活用して、シグナル番号が特定の意味を持つ型であることを強制し、コードの可読性と型安全性を向上させるための変更です。これにより、誤った値がシグナルとして扱われるリスクが低減されます。
  • signals テーブルの追加: シグナル番号とその説明的な文字列名をマッピングするsignalsというstring型の配列が追加されました。このテーブルは、runtime·signame関数が提供していた機能(シグナル番号からシグナル名を取得する)をGo言語側で実現します。これにより、Goプログラムがシグナルに関する情報をより簡単に、かつGoのイディオムに沿った形で取得できるようになります。

これらの変更は全体として、FreeBSD-386環境におけるGoのシグナル処理の堅牢性を高め、システムコールインターフェースの正確性を向上させることを目的としています。特に、シグナル関連の定義をより型安全にし、シグナル名取得のロジックをGo言語側に集約することで、クロスプラットフォーム対応の品質と保守性が向上しています。

関連リンク

参考にした情報源リンク

  • Web search results for "golang freebsd-386 build issues 2012 golang.org/cl/5659045" (via Google Search)
  • Go言語の公式ドキュメントおよびソースコード
  • FreeBSDのシステムプログラミングに関する一般的な知識