[インデックス 10420] ファイルの概要
このコミットは、Go言語のcov
ツール(カバレッジツール)におけるPlan 9ビルドの修正に関するものです。具体的には、src/cmd/cov/main.c
ファイル内のインクルードヘッダーと、プロセス実行に使用される関数呼び出しが変更されています。
コミット
commit 293059ad85e95749f937fff04a96a8ec9b31136f
Author: Lucio De Re <lucio.dere@gmail.com>
Date: Wed Nov 16 16:23:50 2011 -0500
cov: fix for Plan 9 build
R=golang-dev
CC=golang-dev, rsc
https://golang.org/cl/5374086
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/293059ad85e95749f937fff04a96a8ec9b31136f
元コミット内容
cov: fix for Plan 9 build
このコミットは、Go言語のカバレッジツールであるcov
がPlan 9オペレーティングシステム上で正しくビルドおよび動作するようにするための修正です。
変更の背景
Go言語は、その設計者であるRobert Griesemer、Rob Pike、Ken ThompsonがBell LabsでPlan 9オペレーティングシステムの開発に深く関わっていたため、Plan 9と歴史的・技術的に密接な関係があります。Goの設計思想、ツールチェイン(アセンブラ、リンカ、コンパイラ)、さらには標準ライブラリの一部は、Plan 9の経験から大きな影響を受けています。
このコミットが行われた2011年当時、Goはまだ比較的新しい言語であり、様々なプラットフォームでの互換性やビルドの問題が頻繁に発生していました。特にPlan 9のようなニッチな、しかしGoの開発者にとっては重要なプラットフォームでの互換性維持は、初期のGo開発において重要な課題の一つでした。
src/cmd/cov/main.c
は、Goのカバレッジツールの一部であり、C言語で書かれています。Plan 9環境でのビルドや実行において、標準Cライブラリの関数やヘッダーの利用方法、あるいはシステムコール(特にプロセス実行関連)の挙動に差異があったため、それらをPlan 9の慣習に合わせて修正する必要がありました。
具体的には、execv
関数がPlan 9環境では適切に動作しない、あるいはexec
関数がより適切である、または特定のヘッダーファイルが不要であるといった問題があったと考えられます。
前提知識の解説
Plan 9 from Bell Labs
Plan 9 from Bell Labsは、ベル研究所で開発された分散オペレーティングシステムです。Unixの設計思想をさらに推し進め、「すべてをファイルとして扱う」という原則を徹底しています。ネットワーク上のリソース(ファイル、デバイス、プロセスなど)もすべてファイルシステムとして表現され、標準的なファイル操作インターフェースを通じてアクセスできます。Go言語の設計者たちはPlan 9の開発に深く関わっており、Goの設計思想やツールチェインに大きな影響を与えています。
C言語におけるexec
ファミリー関数
C言語の標準ライブラリには、現在のプロセスイメージを新しいプロセスイメージに置き換えるためのexec
ファミリー関数群が存在します。これらの関数は、新しいプログラムを現在のプロセス空間で実行するために使用されます。exec
ファミリーには、引数の渡し方や環境変数の扱いによっていくつかのバリエーションがあります。
execv
:v
は「vector(ベクトル)」を意味し、コマンドライン引数をヌル終端された文字列の配列(char *const argv[]
)として受け取ります。exec
: このコミットでexecv
から変更されたexec
は、通常、exec
ファミリーの総称として使われますが、特定のシステムコールやライブラリ関数としてexec
という名前で提供されることもあります。Plan 9のCライブラリでは、exec
がより一般的なプロセス実行関数として提供されていた可能性があります。Unix系システムでは、exec
という名前の関数は通常存在せず、execl
,execv
,execle
,execve
,execlp
,execvp
などの具体的な関数が使われます。このコミットの文脈では、Plan 9のlibc
におけるexec
関数を指していると考えられます。
exec
ファミリー関数が成功した場合、呼び出し元のプロセスは新しいプログラムに置き換えられるため、関数は呼び出し元に戻りません。エラーが発生した場合のみ、-1を返します。
C言語のヘッダーファイル
C言語では、標準ライブラリ関数やマクロ、型定義などを利用するために、対応するヘッダーファイルをインクルードする必要があります。
<time.h>
: 時間関連の関数(例:time
,difftime
)や型(例:time_t
,struct tm
)を定義します。<ctype.h>
: 文字の分類や変換を行う関数(例:isalpha
,isdigit
,tolower
)を定義します。<u.h>
,<libc.h>
,<bio.h>
: これらはPlan 9固有のヘッダーファイルである可能性が高いです。<u.h>
: Plan 9のシステムコールや基本的な型定義が含まれることが多いです。<libc.h>
: Plan 9の標準Cライブラリ関数が含まれることが多いです。<bio.h>
: Plan 9のBuffered I/Oライブラリに関連する定義が含まれることが多いです。
"tree.h"
: プロジェクト固有のヘッダーファイルで、おそらくcov
ツール内で使用されるデータ構造(ツリー構造)の定義が含まれています。<ureg_amd64.h>
: AMD64アーキテクチャにおけるユーザーレジスタの定義に関連するヘッダーファイルである可能性が高いです。デバッガやプロファイラのような低レベルのツールで利用されることがあります。
技術的詳細
このコミットは、src/cmd/cov/main.c
ファイルに対して以下の2種類の変更を行っています。
-
不要なヘッダーファイルの削除:
#include <time.h>
#include <ctype.h>
これらのヘッダーファイルが、cov
ツールのPlan 9ビルドにおいて不要であるか、あるいはPlan 9の環境では別の方法で同等の機能が提供されているため、削除されました。これにより、ビルド時の依存関係が減り、コンパイルエラーの回避やビルド時間の短縮に貢献します。
-
プロセス実行関数の変更:
- execv(argv[0], argv);
+ exec(argv[0], argv);
execv
関数からexec
関数への変更が行われました。これは、Plan 9のCライブラリにおいて、execv
が期待通りに動作しないか、あるいはexec
がPlan 9のプロセス実行の標準的なインターフェースであるためと考えられます。Unix系システムではexecv
が一般的ですが、Plan 9ではexec
が直接システムコールをラップしている可能性があります。この変更により、cov
ツールがPlan 9上で外部プログラムを正しく起動できるようになります。
コアとなるコードの変更箇所
--- a/src/cmd/cov/main.c
+++ b/src/cmd/cov/main.c
@@ -7,10 +7,8 @@
*/
#include <u.h>
-#include <time.h>
#include <libc.h>
#include <bio.h>
-#include <ctype.h>
#include "tree.h"
#include <ureg_amd64.h>
@@ -394,7 +392,7 @@ startprocess(char **argv)
pid = getpid();
if(ctlproc(pid, "hang") < 0)
sysfatal("ctlproc hang: %r");
- execv(argv[0], argv);
+ exec(argv[0], argv);
sysfatal("exec %s: %r", argv[0]);
}
if(ctlproc(pid, "attached") < 0 || ctlproc(pid, "waitstop") < 0)
@@ -454,7 +452,6 @@ main(int argc, char **argv)
if(argc == 0) {
*--argv = "6.out";
-#t argc++;
}
fd = open(argv[0], OREAD);
if(fd < 0)
コアとなるコードの解説
ヘッダーファイルの変更
元のコードでは、time.h
とctype.h
がインクルードされていましたが、これらは削除されました。これは、cov
ツールがこれらのヘッダーで提供される関数(時間操作や文字種判定など)をPlan 9環境で直接使用していないか、あるいはPlan 9の標準ライブラリがこれらの機能を別のヘッダー(例: libc.h
)を通じて提供しているためと考えられます。不要なヘッダーを削除することで、コンパイル時の依存関係を減らし、Plan 9環境でのビルドエラーを回避します。
execv
からexec
への変更
startprocess
関数内で、子プロセスを起動する際に使用される関数がexecv
からexec
に変更されました。
- 変更前:
execv(argv[0], argv);
execv
は、実行するプログラムのパス(argv[0]
)と、引数の配列(argv
)を受け取ります。 - 変更後:
exec(argv[0], argv);
exec
は、Plan 9のCライブラリにおけるプロセス実行の主要な関数です。Unix系システムではexecv
が一般的ですが、Plan 9ではexec
がより直接的なシステムコールラッパーとして機能します。この変更は、Plan 9環境でのcov
ツールのプロセス起動の互換性を確保するために不可欠です。
この修正により、cov
ツールがPlan 9上でカバレッジ対象のプログラムを正しく実行し、その挙動を監視できるようになります。
関連リンク
- Go言語公式サイト: https://go.dev/
- Plan 9 from Bell Labs: https://9p.io/plan9/
- Go言語とPlan 9の歴史的関係に関する記事 (例: Go Blog): https://go.dev/blog/history
参考にした情報源リンク
- Go言語の歴史とPlan 9との関係に関する情報源 (Web検索結果より)
- C言語の
exec
ファミリー関数に関するドキュメント (Web検索結果より) - Plan 9のCライブラリに関する一般的な情報 (Web検索結果より)