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

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

このコミットは、Go言語のビルドツールである cmd/dist におけるいくつかの修正を含んでいます。具体的には、標準出力と標準エラー出力の順序の保証と、uname -m コマンドの出力における amd64 の認識に関する改善が行われています。

コミット

  • コミットハッシュ: 650e8de0a5fab5cfa32f83dd6d16cf4cfe950fae
  • 作者: Russ Cox rsc@golang.org
  • 日付: 2012年2月4日 (土) 01:46:46 -0500

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

https://github.com/golang/go/commit/650e8de0a5fab5cfa32f83dd6d16cf4cfe950fae

元コミット内容

cmd/dist: more build fixes

Flush stdout before writing to stderr, to avoid
reordering output.

Allow amd64 from uname -m (FreeBSD).

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

変更の背景

このコミットは、Go言語のビルドプロセスにおける2つの異なる問題に対処しています。

  1. 出力の順序の問題: プログラムが標準出力 (stdout) と標準エラー出力 (stderr) の両方に書き込む際、特にバッファリングの挙動により、出力されるメッセージの順序が意図せず入れ替わってしまうことがあります。cmd/distfatal 関数はエラーメッセージを標準エラー出力に書き込みますが、その前に標準出力に書き込まれたデータがバッファに残っていると、エラーメッセージよりも後に表示されてしまう可能性がありました。これは、ユーザーやログ解析ツールが正確なエラー発生状況を把握する上で混乱を招く可能性があります。
  2. アーキテクチャ検出の問題: cmd/dist は、ビルド対象のホストシステムのアーキテクチャを uname -m コマンドの出力に基づいて自動的に検出します。しかし、FreeBSDなどの一部のシステムでは、amd64 アーキテクチャに対して uname -mamd64 という文字列を返すことがありました。従来のコードでは x86_64 のみを認識していたため、amd64 と返されるシステムで正しくアーキテクチャを識別できず、ビルドが失敗する可能性がありました。

これらの問題を解決し、ビルドプロセスの堅牢性と互換性を向上させることが、このコミットの目的です。

前提知識の解説

  • cmd/dist: Go言語のソースコードからGoツールチェイン自体をビルドするためのコマンドラインツールです。Goのビルドシステムの中核をなす部分であり、クロスコンパイルや異なる環境でのビルドをサポートするために、ホストシステムの情報を正確に取得する必要があります。
  • 標準出力 (stdout) と標準エラー出力 (stderr):
    • 標準出力 (stdout): プログラムの通常の出力(結果、情報メッセージなど)が送られるストリームです。通常はコンソールに表示されます。
    • 標準エラー出力 (stderr): プログラムのエラーメッセージや診断情報が送られるストリームです。これも通常はコンソールに表示されますが、stdoutとは独立してリダイレクトできるため、エラーログの収集などに利用されます。
  • バッファリング: プログラムがファイルやストリームにデータを書き込む際、効率化のためにデータを一時的にメモリに蓄える(バッファリングする)ことがあります。バッファがいっぱいになるか、明示的にフラッシュされるまで、データは実際の出力先に書き込まれません。stdoutは通常行バッファリング(改行コードが出力されるまでバッファリング)またはブロックバッファリング(バッファがいっぱいになるまでバッファリング)されますが、stderrは通常バッファリングされません(または非常に小さいバッファリング)。この違いが、出力順序のずれを引き起こす原因となることがあります。
  • fflush(stdout): C言語の標準ライブラリ関数で、指定された出力ストリームのバッファを強制的にフラッシュ(内容を実際の出力先に書き出す)します。fflush(stdout) は、標準出力のバッファに溜まっているデータを即座にコンソールなどに書き出すことを保証します。
  • uname -m: Unix系システムで実行されるコマンドで、システムのハードウェア名(マシンタイプ)を表示します。例えば、Intel/AMD 64ビットシステムでは x86_64amd64 などの文字列を返します。
  • x86_64amd64: どちらも64ビットのIntel/AMD互換プロセッサアーキテクチャを指す用語です。歴史的な経緯から、Linuxなどでは x86_64 が、FreeBSDなどでは amd64 が使われる傾向があります。これらは実質的に同じアーキテクチャを指します。

技術的詳細

このコミットは、src/cmd/dist/unix.c ファイル内の2つの異なる箇所に修正を加えています。

  1. fatal 関数における fflush(stdout) の追加: fatal 関数は、致命的なエラーが発生した際に呼び出され、エラーメッセージを標準エラー出力 (stderr) に出力します。この修正では、fprintf(stderr, ...) を呼び出す直前に fflush(stdout) が追加されました。これにより、fatal 関数が呼び出される前に標準出力に書き込まれた可能性のあるすべてのデータが、エラーメッセージが出力される前に確実にフラッシュされます。これにより、エラーメッセージが他の出力に埋もれたり、順序が入れ替わったりするのを防ぎ、エラーの可視性と診断の正確性を向上させます。

  2. uname -m の出力における amd64 の認識: main 関数内で、ホストシステムのアーキテクチャを検出するために uname(&u) を呼び出し、その結果 (u.machine) を解析しています。以前のコードでは、u.machinex86_64 を含む場合にのみ gohostarchamd64 に設定していました。この修正では、x86_64 に加えて amd64 という文字列も認識するように条件が拡張されました。具体的には、contains(u.machine, "x86_64") の条件に || contains(u.machine, "amd64") が追加されました。これにより、FreeBSDなどのシステムで uname -mamd64 を返す場合でも、Goのビルドシステムが正しくアーキテクチャを amd64 と認識し、適切なビルド設定を選択できるようになります。これは、Goのクロスプラットフォーム互換性を高める上で重要な変更です。

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

--- a/src/cmd/dist/unix.c
+++ b/src/cmd/dist/unix.c
@@ -470,6 +470,7 @@ fatal(char *msg, ...)
 {
 	va_list arg;

+	fflush(stdout);
 	fprintf(stderr, "go tool dist: ");
 	va_start(arg, msg);
 	vfprintf(stderr, msg, arg);
@@ -654,7 +655,7 @@ main(int argc, char **argv)
 	if(gohostarch == nil) {
 		if(uname(&u) < 0)
 			fatal("uname: %s", strerror(errno));
-		if(contains(u.machine, "x86_64"))
+		if(contains(u.machine, "x86_64") || contains(u.machine, "amd64"))
 		gohostarch = "amd64";
 		else if(hassuffix(u.machine, "86"))
 		gohostarch = "386";

コアとなるコードの解説

  1. fatal 関数内の変更:

    +	fflush(stdout);
    	fprintf(stderr, "go tool dist: ");
    

    fatal 関数は、エラーメッセージを標準エラー出力 (stderr) に書き込む前に、fflush(stdout) を呼び出しています。これにより、標準出力 (stdout) のバッファに保留されているデータがすべて強制的に書き出されます。この操作は、エラーメッセージが他の通常の出力よりも確実に先に表示されるようにするために重要です。もし fflush(stdout) がなければ、stdout のバッファリングの挙動によっては、エラーメッセージが stdout の内容の後に表示されてしまい、ログの解析や問題の特定を困難にする可能性がありました。

  2. main 関数内のアーキテクチャ検出ロジックの変更:

    -		if(contains(u.machine, "x86_64"))
    +		if(contains(u.machine, "x86_64") || contains(u.machine, "amd64"))
    		gohostarch = "amd64";
    

    この部分では、uname -m コマンドの出力 (u.machine) をチェックして、ホストのアーキテクチャを特定しています。変更前は x86_64 という文字列のみを検索していましたが、変更後は x86_64 または amd64 のいずれかの文字列が含まれていれば、gohostarchamd64 に設定するように修正されました。これは、FreeBSDなどの一部のオペレーティングシステムが uname -m の出力として amd64 を返す場合があるため、Goのビルドシステムがこれらの環境でも正しく動作するようにするための互換性向上です。

関連リンク

参考にした情報源リンク