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

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

このコミットは、Go言語のsyscallパッケージにおけるNetBSD向けのz*ファイルを修正するものです。具体的には、src/pkg/syscall/zerrors_netbsd_386.gosrc/pkg/syscall/zerrors_netbsd_amd64.gosrc/pkg/syscall/zsyscall_netbsd_386.goの3つのファイルが変更されています。これらの変更により、NetBSD上の386アーキテクチャでGoが再びコンパイルできるようになります。

コミット

commit a1bf5207af2270fe91934bda2f7b068634e9f1c2
Author: Joel Sing <jsing@google.com>
Date:   Fri May 11 03:47:27 2012 +1000

    syscall: repair netbsd z* files
    
    Manually repair/update z* files for netbsd - this allows Go to
    compile again on 386.
    
    R=golang-dev, rsc, minux.ma
    CC=golang-dev
    https://golang.org/cl/6194064

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

https://github.com/golang/go/commit/a1bf5207af2270fe91934bda2f7b068634e9f1c2

元コミット内容

syscall: repair netbsd z* files Manually repair/update z* files for netbsd - this allows Go to compile again on 386.

変更の背景

このコミットの背景には、Go言語のsyscallパッケージが特定のオペレーティングシステム(OS)とアーキテクチャの組み合わせ(この場合はNetBSDの386アーキテクチャ)でコンパイルできない問題がありました。Goのsyscallパッケージは、OS固有のシステムコールやエラーコード、シグナル定義などを扱うために、z*というプレフィックスを持つファイルを自動生成しています。これらのファイルは、GoプログラムがOSの低レベル機能と連携するために不可欠です。

しかし、何らかの理由でNetBSD/386向けのz*ファイルが正しく生成されず、Goのコンパイルが失敗する状況が発生していました。このコミットは、その自動生成されたファイルに手動で修正を加えることで、コンパイルの問題を一時的に解決し、GoがNetBSD/386上で動作するようにするためのものです。コミットメッセージにある「Manually repair/update」という記述から、これは自動生成プロセスの根本的な問題を解決するのではなく、緊急的な対応であったことが伺えます。

前提知識の解説

  • Go言語のsyscallパッケージ: Go言語の標準ライブラリの一部で、オペレーティングシステムの低レベルな機能(システムコール、プロセス管理、ファイルI/Oなど)にアクセスするためのインターフェースを提供します。OSに依存する部分が多く、各OS・アーキテクチャごとに異なる実装を持つことがあります。
  • z*ファイル: Goのsyscallパッケージ内で見られるzerrors_*.gozsyscall_*.goといったファイル群を指します。これらは通常、Goプロジェクト内のツール(例: mksyscall.plmkerrors.shなど)によって、OSのヘッダーファイルやシステムコール定義から自動生成されます。これには、システムコール番号、エラーコード(Errno)、シグナル番号(Signal)などの定数定義が含まれます。自動生成されることで、OSの変更に追従しやすくなっています。
  • NetBSD: オープンソースのUnix系オペレーティングシステムの一つで、その高い移植性(多くの異なるハードウェアアーキテクチャで動作する能力)で知られています。
  • 386 (i386): Intel 80386プロセッサおよびその互換プロセッサを指す32ビットのCPUアーキテクチャです。
  • amd64 (x86-64): IntelとAMDが共同で開発した64ビットのCPUアーキテクチャです。
  • Unixシグナル: Unix系OSにおいて、プロセスに対して非同期的にイベントを通知するメカニズムです。例えば、SIGINTはプログラムの中断(Ctrl+Cなど)、SIGKILLはプロセスの強制終了、SIGSEGVはセグメンテーション違反などを通知します。Goのsyscallパッケージでは、これらのシグナルを数値定数として定義し、プロセス間通信やエラーハンドリングに利用します。
  • Errno型とSignal: Goのsyscallパッケージ内で定義される型で、それぞれシステムエラーコードとシグナル番号を型安全に扱うために使用されます。これにより、単なる整数値ではなく、意味のある型としてこれらの値を扱えるようになります。

技術的詳細

このコミットの技術的な変更は、主に以下の3つの側面に集約されます。

  1. シグナル定数の定義方法の変更:

    • src/pkg/syscall/zerrors_netbsd_386.gosrc/pkg/syscall/zerrors_netbsd_amd64.goにおいて、これまで一般的なconstブロック内に定義されていたSIG*(シグナル)定数(例: SIGABRT = 0x6)が削除されました。
    • 代わりに、// Signalsというコメントの下に新しいconstブロックが追加され、これらのシグナル定数が明示的にSignal型として定義されるようになりました(例: SIGABRT = Signal(0x6))。これは、シグナルが単なる整数値ではなく、syscall.Signalという特定の型であることを明確にし、型安全性を向上させるための変更です。
  2. シグナル名と番号のマッピングの追加:

    • src/pkg/syscall/zerrors_netbsd_386.goに、var signals = [...]string{...}という新しい配列が追加されました。この配列は、シグナル番号(インデックス)に対応するシグナル名の文字列(例: 1: "hangup", 2: "interrupt")を格納します。
    • これは、既存のvar errors = [...]string{...}(エラー番号とエラーメッセージのマッピング)と同様の構造であり、シグナル番号から人間が読めるシグナル名を取得するためのメカニズムを提供します。これにより、デバッグやログ出力の際にシグナルの意味をより簡単に理解できるようになります。
  3. Killシステムコール関数のシグネチャ変更:

    • src/pkg/syscall/zsyscall_netbsd_386.goにおいて、Kill関数のシグネチャがfunc Kill(pid int, signum int) (err error)からfunc Kill(pid int, signum Signal) (err error)に変更されました。
    • これにより、Killシステムコールに渡されるシグナル番号の引数signumが、従来の汎用的なint型から、より具体的なSignal型に厳密化されました。これは、前述のシグナル定数の型変更と一貫しており、Kill関数がシグナルを扱うことをコードレベルで明確にし、誤った型の値が渡されることを防ぐための改善です。

これらの変更は、GoのsyscallパッケージがNetBSD環境、特に386アーキテクチャにおいて、シグナルをより堅牢かつ型安全に扱うための基盤を強化するものです。自動生成されたファイルに手動で修正を加えることで、コンパイルの問題を回避しつつ、より良い設計パターンを導入しています。

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

src/pkg/syscall/zerrors_netbsd_386.go および src/pkg/syscall/zerrors_netbsd_amd64.go

--- a/src/pkg/syscall/zerrors_netbsd_386.go
+++ b/src/pkg/syscall/zerrors_netbsd_386.go
@@ -907,39 +907,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
--	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
  	SIOCAIFADDR                       = 0x8040691a
  	SIOCAIFGROUP                      = 0x80246987
@@ -1272,6 +1239,43 @@ 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)
+	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",
@@ -1366,3 +1370,39 @@ var errors = [...]string{
  	90: "no message of desired type",
  	91: "not supported",
  }
++
+// 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: "stopped (signal)",
++	18: "stopped",
++	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: "power fail/restart",
++}

src/pkg/syscall/zsyscall_netbsd_386.go

--- a/src/pkg/syscall/zsyscall_netbsd_386.go
+++ b/src/pkg/syscall/zsyscall_netbsd_386.go
@@ -606,7 +606,7 @@ func Issetugid() (tainted bool) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Kill(pid int, signum int) (err error) {
+func Kill(pid int, signum Signal) (err error) {
 	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
 	if e1 != 0 {
 		err = e1

コアとなるコードの解説

zerrors_netbsd_386.go および zerrors_netbsd_amd64.go の変更

これらのファイルは、NetBSDオペレーティングシステムにおけるシステムエラーコードとシグナル定数を定義しています。変更の核心は、シグナル定数(SIGABRTSIGALRMなど)の扱いを改善した点にあります。

  • 削除された部分: 以前は、これらのシグナル定数は他の一般的な定数(SHUT_RDなど)と同じconstブロック内に、単なる整数値として定義されていました。これは、シグナルが持つ特定の意味合いをコード上で明確に表現できていませんでした。
  • 追加された部分(// Signalsブロック): 新しいconstブロックが導入され、シグナル定数がSignal型として明示的に定義されるようになりました(例: SIGABRT = Signal(0x6))。これにより、Goの型システムを活用して、シグナルが単なる数値ではなく、特定の目的を持つ型であることが強制されます。これは、コードの可読性と堅牢性を高めます。例えば、int型の引数を受け取る関数に誤ってシグナル以外の整数値を渡してしまうようなミスを防ぐことができます。
  • 追加された部分(signals配列): var signals = [...]string{...}という配列が追加されました。これは、シグナル番号(配列のインデックス)に対応するシグナルの人間が読める説明文字列を提供します。例えば、signals[1]は"hangup"を返します。この配列は、エラーコードとエラーメッセージをマッピングする既存のerrors配列と同様の役割を果たし、デバッグ時やログ出力時にシグナルの意味を即座に把握するのに役立ちます。

これらの変更は、Goのsyscallパッケージがシグナルをより構造化され、型安全な方法で扱うための重要なステップです。

zsyscall_netbsd_386.go の変更

このファイルは、NetBSDの386アーキテクチャにおけるシステムコール関数のGo言語バインディングを定義しています。

  • Kill関数のシグネチャ変更: Kill関数は、指定されたプロセスにシグナルを送信するためのシステムコールをラップしています。以前は、シグナル番号を表すsignum引数が汎用的なint型でした。このコミットにより、signum引数の型がSignal型に変更されました。
    • func Kill(pid int, signum int) (err error)
    • func Kill(pid int, signum Signal) (err error)
  • この変更は、zerrors_netbsd_386.goで導入されたSignal型と整合性を取るものです。これにより、Kill関数を呼び出す際に、Signal型の定数(例: syscall.SIGKILL)を使用することが推奨され、シグナル番号の誤用を防ぎ、コードの意図をより明確にすることができます。Syscall関数へのuintptr(signum)のキャストは変わっていませんが、GoのコンパイラはSignal型がuintptrに変換可能であることを認識し、型チェックを強化します。

全体として、これらの変更はNetBSD/386環境におけるGoのコンパイル問題を解決しつつ、syscallパッケージ内のシグナル処理の堅牢性と型安全性を向上させるためのものです。

関連リンク

参考にした情報源リンク