[インデックス 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検索結果より)