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

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

このコミットは、Go言語のsyscallパッケージにおけるNetBSD/amd64アーキテクチャ向けの修正です。具体的には、zerrors_netbsd_amd64.goファイルとzsyscall_netbsd_amd64.goファイルに対して、シグナル定数の定義とKill関数の引数型に関する手動での修正が行われています。これは、当時のNetBSD上でのGoのビルド失敗という緊急の課題に対応するためのもので、特にgo_bootstrapツールのビルドを可能にすることを目的としています。

コミット

commit 559c191b8935fc52ec3cfc9f34b58b36777ff213
Author: Benny Siegert <bsiegert@gmail.com>
Date:   Fri Apr 6 07:57:05 2012 -0700

    syscall: manually fix z* for NetBSD/amd64
    
    Building go currently fails on NetBSD, thus the regeneration
    scripts do not run correctly. With these changes, at least
    the go_bootstrap tool builds correctly.
    
    R=golang-dev, r, bradfitz
    CC=golang-dev
    https://golang.org/cl/5695064

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

https://github.com/golang/go/commit/559c191b8935fc52ec3cfc9f34b58b36777ff213

元コミット内容

syscall: manually fix z* for NetBSD/amd64

Building go currently fails on NetBSD, thus the regeneration
scripts do not run correctly. With these changes, at least
the go_bootstrap tool builds correctly.

R=golang-dev, r, bradfitz
CC=golang-dev
https://golang.org/cl/5695064

変更の背景

このコミットが行われた2012年4月当時、NetBSD環境でGo言語のビルドが失敗するという問題が発生していました。Goのシステムコール関連のコード(zerrors_*.gozsyscall_*.goなど)は、通常、各OSやアーキテクチャ固有のヘッダファイルから自動生成されるスクリプトによって生成されます。しかし、ビルド自体が失敗している状況では、これらの自動生成スクリプトも正しく実行できませんでした。

この問題により、Goコンパイラやツールチェインの初期ビルド(ブートストラップビルド)がNetBSD上で行えないという深刻な状況に陥っていました。特に、Goのブートストラッププロセスにおいて重要な役割を果たすgo_bootstrapツールがビルドできないことは、NetBSDでのGoの開発や利用を妨げる大きな障壁となっていました。

このコミットは、自動生成スクリプトが機能しない状況下で、手動でNetBSD/amd64向けのシステムコール定義を修正し、最低限go_bootstrapツールがビルドできるようにするための緊急的な対応として導入されました。これは、完全な解決策ではなく、一時的なワークアラウンドとして位置づけられています。

前提知識の解説

Go言語のシステムコールパッケージ (syscall)

Go言語の標準ライブラリには、オペレーティングシステム(OS)のシステムコールを直接呼び出すためのsyscallパッケージが含まれています。このパッケージは、低レベルなOS機能へのアクセスを提供し、ファイル操作、プロセス管理、ネットワーク通信など、OSに依存する多くの機能の基盤となっています。

syscallパッケージは、OSやアーキテクチャごとに異なるシステムコールの定義や定数(エラーコード、シグナル番号など)を扱う必要があります。そのため、Goのソースコード内では、zerrors_OS_ARCH.gozsyscall_OS_ARCH.goといった命名規則のファイルが多数存在します。これらのファイルは、通常、各OSのC言語のヘッダファイル(例: /usr/include/sys/errno.h, /usr/include/sys/signal.h)から情報を抽出し、Goのコードとして自動生成されます。

自動生成 (zファイル)

Goのソースコードベースでは、zで始まるファイル(例: zerrors_netbsd_amd64.go, zsyscall_netbsd_amd64.go)は、特定のツールやスクリプトによって自動生成されることを示します。これらのファイルは、手動で編集されることを意図しておらず、基となるOSのヘッダファイルや定義が変更された際に再生成されることで、常に最新の状態に保たれます。

自動生成の目的は以下の通りです。

  • OS依存性の吸収: OSやアーキテクチャごとの差異を自動的にGoのコードに反映させ、手動でのメンテナンスの手間を省く。
  • 正確性の確保: 人為的なミスを減らし、OSの公式な定義との整合性を保つ。
  • 移植性: 新しいOSやアーキテクチャへの対応を容易にする。

ブートストラップ (go_bootstrap)

Go言語のコンパイラやツールチェインはGo言語自体で書かれています。そのため、Goの環境を初めて構築する際や、新しいバージョンに更新する際には、既存のGoコンパイラ(またはCコンパイラなど、別の言語のコンパイラ)を使って、新しいGoコンパイラをビルドする必要があります。この自己ホスト型のビルドプロセスを「ブートストラップ」と呼びます。

go_bootstrapツールは、このブートストラッププロセスの一部として使用される、Goの初期ビルドに必要な最小限の機能を提供するツールです。これがビルドできないと、Goのツールチェイン全体をNetBSD上で構築することが不可能になります。

シグナル (Signal型)

Unix系OSにおいて、シグナルはプロセス間通信の一種であり、特定のイベント(例: 割り込み、エラー、子プロセスの終了)が発生したことをプロセスに通知するメカニズムです。各シグナルには、SIGINT(割り込み)、SIGSEGV(セグメンテーション違反)、SIGKILL(強制終了)などの一意の番号と名前が割り当てられています。

Goのsyscallパッケージでは、これらのシグナルを扱うための定数や関数が提供されています。このコミットでは、シグナル定数の定義方法が変更され、Signalという型が導入されています。これは、シグナル番号を単なる整数として扱うのではなく、より型安全な方法で扱うための改善と考えられます。

技術的詳細

このコミットの主要な変更点は、src/pkg/syscall/zerrors_netbsd_amd64.goにおけるシグナル定数の定義方法の変更と、src/pkg/syscall/zsyscall_netbsd_amd64.goにおけるKill関数の引数型の変更です。

zerrors_netbsd_amd64.goの変更

以前のバージョンでは、シグナル定数は単なる整数値として定義されていました。 例: SIGABRT = 0x6

このコミットでは、これらのシグナル定数にSignal()という型キャストが追加されています。 例: SIGABRT = Signal(0x6)

これは、Goの型システムを活用し、シグナル番号をより厳密に扱うための変更です。Signal型は、おそらくsyscallパッケージ内で定義されたカスタム型であり、これにより、シグナル番号が誤って他の整数値として扱われることを防ぎ、コードの可読性と安全性を向上させます。また、この変更に伴い、ファイルの下部にシグナル番号に対応するシグナル名の文字列配列signalsが追加されています。これは、シグナル番号から人間が読めるシグナル名を取得するためのマッピングを提供し、デバッグやログ出力の際に役立ちます。

zsyscall_netbsd_amd64.goの変更

Kill関数は、指定されたプロセスにシグナルを送信するためのシステムコールを呼び出すGoのラッパー関数です。以前の定義では、signum(シグナル番号)引数はint型でした。

変更前: func Kill(pid int, signum int) (err error) 変更後: func Kill(pid int, signum Signal) (err error)

この変更により、Kill関数のsignum引数が、新しく導入されたSignal型を受け取るようになりました。これにより、Kill関数を呼び出す際に、シグナル定数として定義されたSignal型の値のみが渡されることが保証され、型安全性がさらに向上します。

これらの変更は、通常自動生成されるはずのファイルに対して手動で行われたものであり、当時のNetBSDでのビルド問題に対する緊急避難的な措置であったことを示しています。自動生成スクリプトが正常に動作しないため、手動で修正を適用することで、最低限の機能(go_bootstrapのビルド)を回復させようとしたものです。

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

src/pkg/syscall/zerrors_netbsd_amd64.go

--- a/src/pkg/syscall/zerrors_netbsd_amd64.go
+++ b/src/pkg/syscall/zerrors_netbsd_amd64.go
@@ -907,39 +907,39 @@ 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
+	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)
  	SIOCADDMULTI                      = 0x80206931
  	SIOCAIFADDR                       = 0x8040691a
  	SIOCAIFGROUP                      = 0x80286987
@@ -1366,3 +1366,39 @@ var errors = [...]string{
  	90: "no message of desired type",
  	91: "not supported",
 }\n+\n+// Signal table\n+var signals = [...]string{\n+\t1:  \"hangup\",\n+\t2:  \"interrupt\",\n+\t3:  \"quit\",\n+\t4:  \"illegal instruction\",\n+\t5:  \"trace/BPT trap\",\n+\t6:  \"abort trap\",\n+\t7:  \"EMT trap\",\n+\t8:  \"floating point exception\",\n+\t9:  \"killed\",\n+\t10: \"bus error\",\n+\t11: \"segmentation fault\",\n+\t12: \"bad system call\",\n+\t13: \"broken pipe\",\n+\t14: \"alarm clock\",\n+\t15: \"terminated\",\n+\t16: \"urgent I/O condition\",\n+\t17: \"stopped (signal)\",\n+\t18: \"stopped\",\n+\t19: \"continued\",\n+\t20: \"child exited\",\n+\t21: \"stopped (tty input)\",\n+\t22: \"stopped (tty output)\",\n+\t23: \"I/O possible\",\n+\t24: \"cputime limit exceeded\",\n+\t25: \"filesize limit exceeded\",\n+\t26: \"virtual timer expired\",\n+\t27: \"profiling timer expired\",\n+\t28: \"window size changes\",\n+\t29: \"information request\",\n+\t30: \"user defined signal 1\",\n+\t31: \"user defined signal 2\",\n+\t32: \"power fail/restart\",\n+}\n```

### `src/pkg/syscall/zsyscall_netbsd_amd64.go`

```diff
--- a/src/pkg/syscall/zsyscall_netbsd_amd64.go
+++ b/src/pkg/syscall/zsyscall_netbsd_amd64.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_amd64.goの変更点

このファイルは、NetBSD/amd64環境におけるシステムコール関連のエラーコードや定数を定義しています。変更の核心は、シグナル定数(SIGABRT, SIGALRMなど)の定義方法です。

  • 型キャストの追加: 以前はSIGABRT = 0x6のように直接整数値を割り当てていましたが、変更後はSIGABRT = Signal(0x6)のようにSignal型へのキャストが明示的に行われています。これは、Goの型システムを利用して、シグナル番号がSignal型として扱われることを強制し、誤った型での使用を防ぐためのものです。これにより、コンパイル時に型チェックが行われ、より堅牢なコードになります。
  • signals配列の追加: ファイルの末尾にsignalsという名前のstring型配列が追加されています。この配列は、シグナル番号(インデックス)に対応するシグナル名(文字列)を格納しています。例えば、signals[1]は"hangup"(SIGHUP)を返します。これは、デバッグ時やログ出力時にシグナル番号を人間が読める形式に変換するために使用されます。この配列の追加は、Signal型の導入と合わせて、シグナルに関する情報管理を改善する意図があります。

zsyscall_netbsd_amd64.goの変更点

このファイルは、NetBSD/amd64環境におけるシステムコール関数のGoラッパーを定義しています。

  • Kill関数の引数型変更: Kill関数は、指定されたプロセスにシグナルを送信するためのGoの関数です。変更前は、シグナル番号を表すsignum引数が汎用的なint型でした。変更後は、この引数がSignal型に変更されています。これにより、Kill関数を呼び出す際には、zerrors_netbsd_amd64.goで定義されたSignal型のシグナル定数を使用することが強制され、引数の型安全性が向上します。これは、zerrors_netbsd_amd64.goでのSignal型導入と連携した変更であり、システムコールインターフェースの一貫性と安全性を高めるものです。

これらの変更は、通常自動生成されるファイルに対して手動で行われたという点が重要です。これは、当時のNetBSDでのGoのビルド環境が不安定であり、自動生成スクリプトが正常に動作しない状況下で、緊急的に必要な修正を適用するための措置であったことを示しています。この手動修正により、最低限go_bootstrapツールがビルドできるようになり、NetBSDでのGoの開発を継続するための足がかりが作られました。

関連リンク

参考にした情報源リンク