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

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

このコミットは、Go言語のランタイムにおけるビルドの問題を修正することを目的としています。具体的には、src/Make.pkgsrc/pkg/runtime/Makefile のビルド設定が変更され、src/pkg/runtime/traceback_amd64.csrc/pkg/runtime/traceback_x86.c にリネームされました。この変更により、異なるアーキテクチャ(特に386とamd64)間でのトレースバック処理の共通化と、ビルドプロセスの整合性が図られています。

コミット

commit 95907c4752b2e8f0e5f75d43031fc914162bb411
Author: Russ Cox <rsc@golang.org>
Date:   Fri Dec 16 15:46:25 2011 -0500

    runtime: fix build

    TBR=r
    CC=golang-dev
    https://golang.org/cl/5493061

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

https://github.com/golang/go/commit/95907c4752b2e8f0e5f75d43031fc914162bb411

元コミット内容

runtime: fix build

TBR=r
CC=golang-dev
https://golang.org/cl/5493061

変更の背景

このコミットは、Goランタイムのビルドプロセスにおける問題を解決するために行われました。Goの初期のビルドシステムはMakefileベースであり、異なるアーキテクチャやOSに対応するために複雑な設定が必要でした。

この特定の変更は、コードレビューシステム (golang.org/cl/5493061) で議論された内容に基づいています。レビューの過程で、traceback_x86.c がARMアーキテクチャ用のオブジェクトファイルリスト (OFILES_arm) に誤って含まれているという指摘がありました。これは、トレースバック処理が特定のアーキテクチャに依存するにもかかわらず、ビルド設定がその依存関係を正しく扱えていなかったことを示唆しています。

このコミットの目的は、このようなビルドの不整合を解消し、特にx86系のアーキテクチャ(386とamd64)で共通のトレースバックコードを使用できるようにすることで、ビルドの堅牢性と保守性を向上させることにありました。

前提知識の解説

Go言語のビルドシステム (初期)

Go言語の初期のビルドシステムは、主にUnix系の make ユーティリティとMakefileに依存していました。Goのソースコードは、C言語やアセンブリ言語で書かれた部分(特にランタイム)とGo言語で書かれた部分が混在しており、これらを適切にコンパイルしリンクするためにMakefileが用いられていました。

  • Make.pkg: Goのパッケージ(pkg)をビルドするための一般的なルールを定義するMakefileの一部です。.s 拡張子を持つアセンブリファイルや .c 拡張子を持つC言語ファイルをオブジェクトファイル (.$O) にコンパイルするためのルールが含まれています。
  • Makefile (各パッケージ内): 各Goパッケージ(例: src/pkg/runtime/Makefile)には、そのパッケージ固有のビルド設定、依存関係、およびコンパイルされるべきファイルリストが定義されていました。

Goランタイム

Goランタイムは、Goプログラムの実行を管理する低レベルのコンポーネント群です。これには、ガベージコレクション、スケジューラ、メモリ管理、システムコールインターフェース、そしてスタックトレースバックなどの機能が含まれます。ランタイムの多くの部分は、パフォーマンスとシステムとの密接な連携のためにC言語やアセンブリ言語で書かれています。

トレースバック (Traceback)

トレースバック(またはスタックトレース)は、プログラムがクラッシュしたり、特定のイベントが発生したりしたときに、その時点での関数呼び出しの履歴(コールスタック)を表示する機能です。デバッグやエラー解析において非常に重要です。トレースバックの生成は、CPUアーキテクチャに強く依存します。なぜなら、スタックフレームの構造、レジスタの使用方法、関数呼び出し規約などがアーキテクチャごとに異なるためです。

GOOSGOARCH

Goのビルドシステムでは、ターゲットのオペレーティングシステム (GOOS) とアーキテクチャ (GOARCH) を指定することで、クロスコンパイルをサポートしています。

  • GOOS: linux, windows, darwin (macOS) など。
  • GOARCH: amd64, 386, arm など。

これらの変数は、Makefile内で条件付きコンパイルや、特定のアーキテクチャ/OSに特化したファイルを選択するために使用されます。

ビルドタグ (+build ディレクティブ)

Goのソースファイルでは、ファイルの先頭に // +build tag の形式でビルドタグを記述することで、特定の条件が満たされた場合にのみそのファイルをビルド対象に含めることができます。これは、異なるOSやアーキテクチャ、あるいは特定のビルド設定に応じてコードを切り替える際に非常に有用です。例えば、// +build amd64 386 は、GOARCHamd64 または 386 の場合にのみそのファイルがコンパイルされることを意味します。

技術的詳細

このコミットの技術的な核心は、Goランタイムのトレースバック処理を、x86系のアーキテクチャ(386とamd64)で共通化し、ビルド設定を修正することにあります。

  1. traceback_amd64.c から traceback_x86.c へのリネームとビルドタグの追加:

    • 元の src/pkg/runtime/traceback_amd64.c は、amd64アーキテクチャ専用のトレースバックコードでした。
    • このファイルを src/pkg/runtime/traceback_x86.c にリネームすることで、ファイル名がより汎用的なx86系アーキテクチャを指すようになりました。
    • さらに、このファイルに // +build amd64 386 というビルドタグが追加されました。これにより、このCソースファイルは GOARCHamd64 または 386 の場合にのみコンパイルされるようになります。これは、386とamd64のトレースバック処理が非常に似ているため、共通のコードベースで対応できることを示しています。
  2. src/pkg/runtime/Makefile の変更:

    • OFILES_386OFILES_amd64traceback_x86.$O が追加されました。これは、386およびamd64アーキテクチャのビルドにおいて、リネームされた traceback_x86.c から生成されるオブジェクトファイルがリンクされることを明示しています。
    • OFILES_arm にも traceback_x86.$O が追加されていますが、これはコードレビューで指摘されたように、本来はARMアーキテクチャには別のトレースバックコードが必要である可能性を示唆しています。しかし、このコミット時点では、x86系のトレースバックコードが一時的にARMのビルドにも含まれる形になっています(後のコミットで修正される可能性があります)。
    • 汎用的な traceback_$(GOARCH).$O の行が削除されました。これは、特定のアーキテクチャに依存するトレースバックファイルが、より明示的な OFILES_GOARCH 変数で管理されるようになったことを意味します。
    • HFILESasm_$(GOARCH).h が追加されました。これは、アセンブリコードに関連するヘッダーファイルが、ランタイムのビルドに必要な依存関係として明示されたことを示します。
  3. src/Make.pkg の変更:

    • アセンブリファイル (.s) からオブジェクトファイル (.$O) を生成するルールに $(HFILES) が依存関係として追加されました。これは、アセンブリファイルがコンパイルされる際に、ヘッダーファイル(特に asm_$(GOARCH).h のようなアセンブリ関連の定義を含むもの)が変更された場合にも再ビルドがトリガーされるようにするためです。これにより、ビルドの正確性が向上します。
    • runtime.acid.$(GOARCH) のビルドルールに $(AUTOHFILES) が追加されました。runtime.acid は、デバッグ時に構造体内のオフセットを特定するために使用されるファイルであり、自動生成されるヘッダーファイル (AUTOHFILES) に依存することが明示されました。

これらの変更により、Goランタイムのビルドシステムは、特にx86系のアーキテクチャにおけるトレースバック処理のビルドをより正確かつ効率的に行えるようになりました。

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

diff --git a/src/Make.pkg b/src/Make.pkg
index de4c769e5b..c6c47ffd0a 100644
--- a/src/Make.pkg
+++ b/src/Make.pkg
@@ -245,5 +245,5 @@ endif
 %.$O: _obj/%.c $(HFILES)\
 	$(CC) $(CFLAGS) -I . -o "$@" _obj/$*.c

-%.$O: %.s
+%.$O: %.s $(HFILES)\
 	$(AS) $*.s
diff --git a/src/pkg/runtime/Makefile b/src/pkg/runtime/Makefile
index 9fb3a2bbe7..651fa02d0b 100644
--- a/src/pkg/runtime/Makefile
+++ b/src/pkg/runtime/Makefile
@@ -51,6 +51,11 @@ OFILES_windows=\
 OFILES_386=\
 	vop_386.$O\\
 	vlrt_386.$O\\
+\ttraceback_x86.$O\\
+\
+# amd64-specific object files\
+OFILES_amd64=\\
+\ttraceback_x86.$O\\
 \
 # arm-specific object files\
 OFILES_arm=\\
@@ -58,6 +63,7 @@ OFILES_arm=\
 	softfloat_arm.$O\\
 	vop_arm.$O\\
 	vlrt_arm.$O\\
+\ttraceback_x86.$O\\
 \
 OFILES=\\
 	alg.$O\\
@@ -97,7 +103,6 @@ OFILES=\
 	sys_$(GOOS)_$(GOARCH).$O\\
 	thread_$(GOOS).$O\\
 	time.$O\\
-\ttraceback_$(GOARCH).$O\\
 	$(OFILES_$(GOARCH))\\
 	$(OFILES_$(GOOS))\\
 \
@@ -113,6 +118,7 @@ HFILES=\
 	hashmap.h\\
 	malloc.h\\
 	stack.h\\
+\tasm_$(GOARCH).h\\
 	$(AUTOHFILES)\\
 \
 GOFILES+=$(GOFILES_$(GOOS))\
@@ -157,10 +163,8 @@ version_$(GOOS).go:\
 	./goc2c "`pwd`/$<" > $@.tmp\\
 	mv -f $@.tmp $@\\
 \
-%.$O: asm_$(GOARCH).h
-\
 # for discovering offsets inside structs when debugging\
-runtime.acid.$(GOARCH): runtime.h proc.c\
+runtime.acid.$(GOARCH): runtime.h proc.c $(AUTOHFILES)\
 	$(CC) $(CFLAGS) -a proc.c >$@\\
 \
 # 386 traceback is really amd64 traceback\
diff --git a/src/pkg/runtime/traceback_amd64.c b/src/pkg/runtime/traceback_x86.c
similarity index 99%
rename from src/pkg/runtime/traceback_amd64.c
rename to src/pkg/runtime/traceback_x86.c
index fedda797c2..be35bab002 100644
--- a/src/pkg/runtime/traceback_amd64.c
+++ b/src/pkg/runtime/traceback_x86.c
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.\
 \
+// +build amd64 386\
+\
 #include "runtime.h"\
 #include "arch_GOARCH.h"\
 #include "malloc.h"\

コアとなるコードの解説

src/Make.pkg の変更

  • - %.$O: %.s から + %.$O: %.s $(HFILES):
    • これは、アセンブリ言語のソースファイル (.s) からオブジェクトファイル (.$O) を生成するMakefileのルールです。
    • 変更前は、アセンブリファイル自体が変更された場合にのみ再コンパイルが行われていました。
    • 変更後は、$(HFILES)(ヘッダーファイル群)が依存関係に追加されました。これにより、アセンブリコードがインクルードしているヘッダーファイル(例: asm_$(GOARCH).h)が変更された場合にも、関連するアセンブリファイルが再コンパイルされるようになり、ビルドの整合性が保たれます。

src/pkg/runtime/Makefile の変更

  • OFILES_386 および OFILES_amd64 への traceback_x86.$O の追加:

    • OFILES_386 は32ビットx86アーキテクチャ(Intel 386互換)用のオブジェクトファイルリストです。
    • OFILES_amd64 は64ビットx86アーキテクチャ(AMD64/x86-64)用のオブジェクトファイルリストです。
    • これらのリストに traceback_x86.$O が追加されたことで、386およびamd64のビルドプロセスにおいて、共通の traceback_x86.c からコンパイルされたオブジェクトファイルがランタイムにリンクされることが明示されました。
  • OFILES_arm への traceback_x86.$O の追加:

    • ARMアーキテクチャ用のオブジェクトファイルリストにも traceback_x86.$O が追加されています。これは、コードレビューで指摘されたように、論理的にはARMにはARM固有のトレースバックコードが必要であるため、一時的な措置であるか、あるいは当時のGoのビルドシステムにおける特定の制約を示している可能性があります。
  • - traceback_$(GOARCH).$O の削除:

    • これは、GOARCH 変数に基づいて動的にトレースバックファイルを選択する汎用的なルールでした。
    • この行が削除されたことで、トレースバック関連のオブジェクトファイルは、各アーキテクチャ固有の OFILES_GOARCH 変数で明示的に管理されるようになりました。これにより、どのトレースバックファイルがどのアーキテクチャでビルドされるかがより明確になります。
  • HFILES への asm_$(GOARCH).h の追加:

    • HFILES は、ランタイムのビルドに必要な共通のヘッダーファイルリストです。
    • asm_$(GOARCH).h は、特定のアーキテクチャのアセンブリコードに関連する定義を含むヘッダーファイルです。これが追加されたことで、アセンブリコードとCコード間のインターフェースが変更された場合にも、ランタイム全体が適切に再ビルドされるようになります。
  • runtime.acid.$(GOARCH) ルールの変更:

    • runtime.acid.$(GOARCH) は、デバッグ目的で構造体のオフセットを調べるために使用されるファイルです。
    • このターゲットの依存関係に $(AUTOHFILES)(自動生成されるヘッダーファイル)が追加されました。これにより、自動生成されたヘッダーファイルが変更された場合にも、runtime.acid が再生成され、デバッグ情報の正確性が保たれます。

src/pkg/runtime/{traceback_amd64.c => traceback_x86.c} の変更

  • ファイルのリネーム:

    • src/pkg/runtime/traceback_amd64.csrc/pkg/runtime/traceback_x86.c にリネームされました。これは、このトレースバックコードがamd64だけでなく、386アーキテクチャにも適用可能であることを示すための変更です。
  • // +build amd64 386 ビルドタグの追加:

    • リネームされた traceback_x86.c の先頭にこのビルドタグが追加されました。
    • このタグは、Goのビルドシステムに対して、このファイルは GOARCHamd64 または 386 の場合にのみコンパイル対象とすることを指示します。これにより、異なるアーキテクチャ間で共通のトレースバックコードを使用しつつ、ビルドの対象を適切に制限することができます。

これらの変更は、Goランタイムのビルドシステムをより堅牢にし、特にx86系のアーキテクチャにおけるトレースバック処理の管理を改善することを目的としています。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント (当時のビルドシステムに関する情報を含む)
  • Go言語のソースコード (特に src/Make.pkgsrc/pkg/runtime/Makefile の歴史的な変更履歴)
  • Go言語のビルドタグに関するドキュメント (例: go help build)
  • Makefileの一般的な構文とルールに関する情報
  • スタックトレースバックの概念とアーキテクチャ依存性に関する一般的なプログラミング知識
  • https://golang.org/cl/5493061 (Web Fetchで取得した情報)
  • https://github.com/golang/go/commit/95907c4752b2e8f0e5f75d43031fc914162bb411 (コミットページ)