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

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

このコミットは、Go言語のビルドシステム (cmd/dist) と、macOS上でのデバッガーツール (cov および prof) のインストールを補助するスクリプト (sudo.bash) に関連する変更です。具体的には、cov または prof ツールが存在しない場合に、sudo.bash の実行を促すメッセージが表示されないように修正しています。これにより、ユーザーが不要なメッセージに惑わされることを防ぎ、よりスムーズな開発体験を提供します。

コミット

commit a9de5bb3eb36fcae6d0744603a5bd7a5be606796
Author: Shenghou Ma <minux.ma@gmail.com>
Date:   Mon Apr 2 22:33:38 2012 +0800

    cmd/dist, sudo.bash: don't mention sudo.bash if cov or prof is not present
            Fixes #3422.
    
    R=golang-dev, rsc
    CC=golang-dev
    https://golang.org/cl/5967057

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

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

元コミット内容

cmd/dist, sudo.bash: don't mention sudo.bash if cov or prof is not present
        Fixes #3422.

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

変更の背景

Go言語のビルドプロセスにおいて、macOS環境ではデバッガーツール(covprof)が特定の権限(setgid procmod)でインストールされている必要があります。このインストールを補助するために sudo.bash というスクリプトが提供されていました。

しかし、これらのデバッガーツールがビルドされていない、あるいは利用できない環境では、sudo.bash の実行を促すメッセージが表示されることがありました。これは、ユーザーにとって不要な情報であり、混乱を招く可能性がありました。

このコミットは、このような状況を改善するために行われました。具体的には、cov または prof ツールが実際に存在するかどうかを確認し、存在しない場合には sudo.bash に関するメッセージを表示しないようにすることで、ユーザーエクスペリエンスを向上させることを目的としています。コミットメッセージにある Fixes #3422 は、Goの内部イシュートラッカーにおける特定の課題を解決することを示しています。

前提知識の解説

  • cmd/dist: Go言語のソースコードからGoツールチェイン全体をビルドするためのコマンドです。Goのビルドシステムの中核をなす部分であり、様々なプラットフォーム向けのビルドを管理します。
  • sudo.bash: macOS環境において、Goのデバッガーツール(covprof)を適切な権限でインストールするためのシェルスクリプトです。macOSでは、デバッガがプロセス情報を取得するために特別な権限を必要とすることがあり、setgid procmod はそのための設定の一つです。
  • cov: Go言語のコードカバレッジツールです。テスト実行時にどのコードが実行されたかを測定し、カバレッジレポートを生成します。
  • prof: Go言語のプロファイリングツールです。CPU使用率、メモリ割り当て、ゴルーチンスタックトレースなど、プログラムの実行時のパフォーマンスデータを収集・分析します。
  • setgid procmod: Unix系システムにおけるファイルパーミッションの一種で、setgid ビットが設定された実行ファイルは、そのファイルのグループIDで実行されます。procmod は、プロセス情報を操作するための特定の権限や機能を示唆している可能性があります。macOSのデバッガがプロセスにアタッチして情報を取得するためには、このような特別な権限が必要となることがあります。
  • Buf: Goの内部で使われるバッファ構造体で、文字列操作やパス構築などに利用されます。

技術的詳細

この変更は、主に src/cmd/dist/build.csrc/sudo.bash の2つのファイルにわたって行われています。

  1. src/cmd/dist/build.c の変更:

    • cmdbanner 関数は、Goのビルドが完了した際に表示されるメッセージ(バナー)を生成する役割を担っています。
    • 以前は、macOS (darwin) 環境であれば無条件に sudo.bash の実行を促すメッセージが表示されていました。
    • 変更後、このメッセージの表示条件に isfile(bpathf(&path, "%s/cov", tooldir)) というチェックが追加されました。これは、tooldir (Goツールがインストールされるディレクトリ) 内に cov というファイル(実行可能ツール)が存在するかどうかを確認しています。
    • Buf 型の変数 path が新しく追加され、binit(&path) で初期化され、bfree(&path) で解放されています。これは、isfile 関数に渡すパスを構築するために使用されます。
    • これにより、cov ツールが存在しない場合は、sudo.bash に関するメッセージが表示されなくなります。
  2. src/sudo.bash の変更:

    • このスクリプトの冒頭に、covprof ツールが存在するかどうかを確認するロジックが追加されました。
    • eval $(go env) コマンドでGoの環境変数を読み込み、特に GOTOOLDIR の値を取得します。
    • if ! [ -x $GOTOOLDIR/cov -a -x $GOTOOLDIR/prof ]; then という条件文が追加されています。
      • -x はファイルが実行可能であるかをチェックするテスト演算子です。
      • -a は論理AND演算子です。
      • この条件は、「$GOTOOLDIR/cov が実行可能でない、または $GOTOOLDIR/prof が実行可能でない」場合に真となります。
    • もしこの条件が真であれば、つまり cov または prof のいずれか、あるいは両方が存在しないか実行可能でない場合、「You don't need to run sudo.bash.」というメッセージを標準エラー出力に表示し、終了コード 2 でスクリプトを終了します。
    • これにより、ユーザーが誤って sudo.bash を実行しようとした際に、不要な操作を回避できるようになります。

これらの変更は、Goのビルドシステムとツールの連携をよりインテリジェントにし、ユーザーが直面する可能性のある混乱を減らすことに貢献しています。

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

src/cmd/dist/build.c

--- a/src/cmd/dist/build.c
+++ b/src/cmd/dist/build.c
@@ -19,7 +19,7 @@ char *goos;
 char *goroot = GOROOT_FINAL;
 char *goroot_final = GOROOT_FINAL;
 char *workdir;
-char	*tooldir;
+char *tooldir;
 char *gochar;
 char *goversion;
 char *slash;	// / for unix, \ for windows
@@ -1462,7 +1462,7 @@ void
 cmdbanner(int argc, char **argv)
 {
 	char *pathsep;
-\tBuf b, b1, search;\n+\tBuf b, b1, search, path;\n \n \tARGBEGIN{\n \tcase \'v\':\n@@ -1478,6 +1478,7 @@ cmdbanner(int argc, char **argv)\n \tbinit(&b);\n \tbinit(&b1);\n \tbinit(&search);\n+\tbinit(&path);\n \n \txprintf(\"\\n\");
 \txprintf(\"---\\n\");
 \n@@ -1495,9 +1496,10 @@ cmdbanner(int argc, char **argv)\n \t\txprintf(\"*** You need to add %s to your PATH.\\n\", gobin);\n \n \tif(streq(gohostos, \"darwin\")) {\n-\t\txprintf(\"\\n\"\n-\t\t\t\"On OS X the debuggers must be installed setgid procmod.\\n\"\n-\t\t\t\"Read and run ./sudo.bash to install the debuggers.\\n\");\n+\t\tif(isfile(bpathf(&path, \"%s/cov\", tooldir)))\n+\t\t\txprintf(\"\\n\"\n+\t\t\t\t\"On OS X the debuggers must be installed setgid procmod.\\n\"\n+\t\t\t\t\"Read and run ./sudo.bash to install the debuggers.\\n\");\n \t}\n \n \tif(!streq(goroot_final, goroot)) {\n@@ -1509,6 +1511,7 @@ cmdbanner(int argc, char **argv)\n \tbfree(&b);\n \tbfree(&b1);\n \tbfree(&search);\n+\tbfree(&path);\n }\n \n // Version prints the Go version.\n```

### `src/sudo.bash`

```diff
--- a/src/sudo.bash
+++ b/src/sudo.bash
@@ -12,12 +12,17 @@ Darwin)
 	exit 0
 esac
 
+eval $(go env)
+if ! [ -x $GOTOOLDIR/cov -a -x $GOTOOLDIR/prof ]; then
+	echo \"You don\'t need to run sudo.bash.\" >&2
+	exit 2
+fi
+\n if [[ ! -d /usr/local/bin ]]; then
 	echo 1>&2 \'sudo.bash: problem with /usr/local/bin; cannot install tools.\'\n \texit 2
 fi
 \n-eval $(go env)\n cd $(dirname $0)\n for i in prof cov
 do

コアとなるコードの解説

src/cmd/dist/build.c の変更点

cmdbanner 関数内の変更は、macOS (darwin) 環境でのメッセージ表示ロジックを改善しています。

 if(streq(gohostos, "darwin")) {
-		xprintf("\n"
-			"On OS X the debuggers must be installed setgid procmod.\n"
-			"Read and run ./sudo.bash to install the debuggers.\n");
+		if(isfile(bpathf(&path, "%s/cov", tooldir)))
+			xprintf("\n"
+				"On OS X the debuggers must be installed setgid procmod.\n"
+				"Read and run ./sudo.bash to install the debuggers.\n");
 	}
  • 変更前は、gohostos が "darwin" (macOS) であれば、無条件にデバッガーのインストールに関するメッセージが表示されていました。
  • 変更後、if(isfile(bpathf(&path, "%s/cov", tooldir))) という条件が追加されました。
    • tooldir はGoツールがインストールされるディレクトリのパスです。
    • bpathf(&path, "%s/cov", tooldir) は、tooldir の下に cov というパスを構築し、それを path バッファに格納します。
    • isfile() 関数は、指定されたパスにファイルが存在するかどうかをチェックします。
  • この変更により、cov ツールが実際にビルドされ、tooldir 内に存在する場合にのみ、sudo.bash の実行を促すメッセージが表示されるようになりました。これにより、cov ツールが利用できない環境で不要なメッセージが表示されることがなくなります。

また、Buf path; の宣言と binit(&path);, bfree(&path); の追加は、この新しいファイルパスチェックのために必要なバッファの初期化と解放を行っています。

src/sudo.bash の変更点

sudo.bash スクリプトの冒頭に追加されたロジックは、スクリプト自体の実行を早期に終了させるためのものです。

eval $(go env)
if ! [ -x $GOTOOLDIR/cov -a -x $GOTOOLDIR/prof ]; then
	echo "You don't need to run sudo.bash." >&2
	exit 2
fi
  • eval $(go env): Goの環境変数(特に GOTOOLDIR)を現在のシェルセッションに読み込みます。これにより、GOTOOLDIR 変数を使用してGoツールがインストールされているディレクトリのパスにアクセスできるようになります。
  • if ! [ -x $GOTOOLDIR/cov -a -x $GOTOOLDIR/prof ]; then:
    • [ -x $GOTOOLDIR/cov ]: $GOTOOLDIR/cov が実行可能ファイルであるかをチェックします。
    • [ -x $GOTOOLDIR/prof ]: $GOTOOLDIR/prof が実行可能ファイルであるかをチェックします。
    • -a は論理AND演算子です。したがって、[ -x $GOTOOLDIR/cov -a -x $GOTOOLDIR/prof ] は、「covprof の両方が実行可能である」場合に真となります。
    • ! は論理NOT演算子です。したがって、! [ ... ] は、「covprof の両方が実行可能である」という条件が偽の場合、つまり「cov または prof の少なくとも一方が実行可能でない」場合に真となります。
  • echo "You don't need to run sudo.bash." >&2: 上記の条件が真の場合、つまり cov または prof が存在しないか実行可能でない場合に、このメッセージを標準エラー出力 (>&2) に表示します。
  • exit 2: スクリプトを終了コード 2 で終了します。

この変更により、sudo.bash が実行された際に、cov または prof ツールが利用できない環境であれば、すぐにユーザーにその旨を伝え、不要な処理をスキップするようになりました。これは、ユーザーが誤ってスクリプトを実行してしまったり、ツールの存在しない環境で不必要なエラーに遭遇したりするのを防ぐための堅牢化です。

関連リンク

  • Go言語の公式ウェブサイト: https://golang.org/
  • Go言語のIssue Tracker (このコミットで言及されている #3422 は、Goの内部イシュートラッカーのIDである可能性が高いです。公開されているGitHubリポジトリのIssueとは異なる場合があります。): https://github.com/golang/go/issues
  • Goのコードレビューシステム (Gerrit): https://golang.org/cl/5967057

参考にした情報源リンク