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

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

このコミットは、Go言語のruntime/pprofパッケージにおけるテストの修正に関するものです。具体的には、macOSの特定のバージョン(LeopardおよびSnow Leopard)の64-bit環境において、CPUプロファイルのテストが正しく動作しない問題に対応するため、該当環境でのテスト実行をスキップするように変更しています。

コミット

commit b37841cc0659f07bccea5ff7d601934ccc26e964
Author: Russ Cox <rsc@golang.org>
Date:   Wed Mar 7 11:44:54 2012 -0500

    runtime/pprof: disable test on Leopard 64-bit
    
    Fixes #3234.
    
    R=golang-dev, gri
    CC=golang-dev
    https://golang.org/cl/5756078

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

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

元コミット内容

このコミットは、runtime/pprofパッケージ内のテストが、macOSのLeopardおよびSnow Leopardの64-bit環境で失敗する問題を修正するために行われました。コミットメッセージには「Fixes #3234」とありますが、公開されているGoのIssueトラッカー上では、この番号のIssueはpprofやmacOSの特定のバージョンに関するものではないようです。これは、当時の内部的なIssue番号であるか、あるいはIssueトラッカーの変更により参照できなくなっている可能性があります。

変更の背景

Go言語のruntime/pprofパッケージは、Goプログラムのプロファイリング機能を提供します。CPUプロファイルは、プログラムがCPU時間をどこで消費しているかを特定するのに役立ちます。しかし、特定のオペレーティングシステムやアーキテクチャの組み合わせにおいて、プロファイリングのメカニズムが期待通りに動作しないことがあります。

このコミットが行われた2012年当時、macOSのLeopard (10.5) およびSnow Leopard (10.6) の64-bit環境において、runtime/pprofのCPUプロファイルテストが不安定であったり、誤った結果を返したりする問題が存在していました。これは、これらの古いmacOSバージョンにおけるカーネルの動作や、Goランタイムがプロファイリング情報を収集する方法との間の非互換性が原因であると考えられます。テストが不安定な環境で実行されると、CI/CDパイプラインでの誤った失敗を引き起こし、開発の妨げとなるため、一時的にテストを無効化する措置が取られました。

前提知識の解説

runtime/pprofパッケージ

runtime/pprofは、Go言語の標準ライブラリの一部であり、Goプログラムの実行時プロファイリング機能を提供します。これにより、開発者はCPU使用率、メモリ割り当て、ゴルーチン、ブロックされた操作など、プログラムの様々な側面を分析できます。プロファイリングデータは通常、pprofツールで視覚化できる形式で出力され、パフォーマンスのボトルネックを特定するのに役立ちます。

macOSのカーネルバージョンとOSバージョン

macOSは、その基盤としてDarwinと呼ばれるUnix系オペレーティングシステムを使用しています。DarwinのカーネルはXNU(XNU is Not Unix)と呼ばれ、そのバージョンは「Darwin Kernel Version」として識別されます。

  • Darwin Kernel Version 10: macOS Snow Leopard (10.6) に対応します。
  • Darwin Kernel Version 11: macOS Lion (10.7) に対応します。

コミットメッセージやコード内のコメントにある「Leopard」はmacOS 10.5、「Snow Leopard」はmacOS 10.6を指します。これらのバージョンは、特に64-bit環境でのシステムコールやシグナルハンドリングの挙動において、後のmacOSバージョンとは異なる点がありました。

64-bit環境での問題

64-bit環境では、ポインタのサイズが32-bit環境の2倍になり、アドレス空間が大幅に拡張されます。これにより、より多くのメモリを扱えるようになりますが、同時にシステムコールや低レベルの操作において、32-bit環境とは異なる挙動を示すことがあります。特に、プロファイリングのような低レベルのシステム情報にアクセスする機能は、OSのカーネルやアーキテクチャに強く依存するため、特定の64-bit環境で問題が発生する可能性がありました。

技術的詳細

このコミットの技術的な核心は、uname -aコマンドの出力を用いて、実行環境が特定のmacOSの64-bitカーネルであるかどうかを判定し、その場合にテストをスキップするという点にあります。

uname -aコマンドは、システムの情報を表示します。その出力には、カーネルのバージョン、ビルド情報、アーキテクチャなどが含まれます。例えば、Darwin Kernel Version 10.8.0 root:xnu-1504.15.3~1/RELEASE_X86_64のような文字列が含まれることがあります。

  • Darwin Kernel Version 10: これはmacOS Snow Leopard (10.6) のカーネルバージョンを示します。
  • RELEASE_X86_64: これはシステムが64-bitのx86アーキテクチャで動作していることを示します。

元のコードでは、strings.Contains(vers, "Darwin Kernel Version 10.8.0") && strings.Contains(vers, "root:xnu-1504.15.3~1/RELEASE_X86_64")という非常に具体的な文字列マッチングを行っていました。これは、特定のマイナーバージョン(10.8.0)と特定のビルド(xnu-1504.15.3~1)に限定してテストをスキップするものでした。コメントには「known-broken kernel (64-bit Snow Leopard)」とあり、この特定のカーネルビルドで問題が確認されていたことを示唆しています。

しかし、このコミットでは、より広範な条件に拡張されました。strings.Contains(vers, "Darwin Kernel Version 10") && strings.Contains(vers, "RELEASE_X86_64")という条件に変更することで、Darwin Kernel Version 10(つまりmacOS Snow Leopard)の任意のビルド、およびDarwin Kernel Version 10より前のバージョン(つまりmacOS Leopard)の64-bit環境も対象に含めるようになりました。これは、問題が特定のビルドに限定されるものではなく、LeopardおよびSnow Leopardの64-bit環境全般にわたるものであるという認識に基づいています。

この変更により、不安定な環境でのテスト失敗を回避し、CI/CDの安定性を向上させることができました。

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

--- a/src/pkg/runtime/pprof/pprof_test.go
+++ b/src/pkg/runtime/pprof/pprof_test.go
@@ -24,8 +24,9 @@ func TestCPUProfile(t *testing.T) {
 		}
 		vers := string(out)
 		t.Logf("uname -a: %v", vers)
-		if strings.Contains(vers, "Darwin Kernel Version 10.8.0") && strings.Contains(vers, "root:xnu-1504.15.3~1/RELEASE_X86_64") {
-			t.Logf("skipping test on known-broken kernel (64-bit Snow Leopard)")
+		// Lion uses "Darwin Kernel Version 11".
+		if strings.Contains(vers, "Darwin Kernel Version 10") && strings.Contains(vers, "RELEASE_X86_64") {
+			t.Logf("skipping test on known-broken kernel (64-bit Leopard / Snow Leopard)")
 			return
 		}
 	case "plan9":

コアとなるコードの解説

変更されたコードは、TestCPUProfile関数内にあります。このテスト関数は、CPUプロファイリング機能が正しく動作するかどうかを検証します。

  1. uname -aの実行と出力の取得:

    cmd := exec.Command("uname", "-a")
    out, err := cmd.Output()
    if err != nil {
        t.Logf("uname -a: %v", err)
        return
    }
    vers := string(out)
    t.Logf("uname -a: %v", vers)
    

    この部分では、uname -aコマンドを実行し、その標準出力をvers変数に文字列として格納しています。t.Logfはテストのログにuname -aの出力を記録します。

  2. テストスキップ条件の変更:

    -		if strings.Contains(vers, "Darwin Kernel Version 10.8.0") && strings.Contains(vers, "root:xnu-1504.15.3~1/RELEASE_X86_64") {
    -			t.Logf("skipping test on known-broken kernel (64-bit Snow Leopard)")
    +		// Lion uses "Darwin Kernel Version 11".
    +		if strings.Contains(vers, "Darwin Kernel Version 10") && strings.Contains(vers, "RELEASE_X86_64") {
    +			t.Logf("skipping test on known-broken kernel (64-bit Leopard / Snow Leopard)")
    			return
    		}
    

    このif文が変更の核心です。

    • 変更前: vers文字列が「Darwin Kernel Version 10.8.0」と「root:xnu-1504.15.3~1/RELEASE_X86_64」の両方を含む場合にテストをスキップしていました。これは、特定のSnow Leopard 64-bitカーネルビルドに限定された条件でした。
    • 変更後: vers文字列が「Darwin Kernel Version 10」と「RELEASE_X86_64」の両方を含む場合にテストをスキップするように条件が緩和されました。
      • strings.Contains(vers, "Darwin Kernel Version 10"): これは、macOS Snow Leopard (10.6) のすべてのビルド、およびそれ以前のmacOS Leopard (10.5) の一部のビルド(Darwin Kernel Version 9.x.x)も間接的に含む可能性がありますが、主にDarwin Kernel Version 10をターゲットにしています。
      • strings.Contains(vers, "RELEASE_X86_64"): これは、システムが64-bitモードで動作していることを確認します。
    • コメントも「Lion uses "Darwin Kernel Version 11".」と追記され、新しい条件が「64-bit Leopard / Snow Leopard」を対象としていることが明記されました。

この変更により、より広範な古いmacOSの64-bit環境でTestCPUProfileがスキップされるようになり、これらの環境でのテストの不安定性が解消されました。returnステートメントにより、条件が満たされた場合はそれ以降のテストロジックは実行されません。

関連リンク

  • Go言語のpprofパッケージに関する公式ドキュメント: https://pkg.go.dev/runtime/pprof
  • macOSのバージョン履歴とDarwinカーネルバージョンに関する情報(非公式リソースの可能性あり、検索で確認してください)

参考にした情報源リンク

  • Go言語のIssueトラッカー(当時のIssue #3234が公開されているか確認しましたが、関連性のあるものは見つかりませんでした。これは内部的なIssueであるか、非常に古い情報である可能性があります。)
  • unameコマンドに関するドキュメントやmanページ
  • macOSのカーネルバージョンとOSバージョンの対応に関する一般的な情報(WikipediaやApple Developer Documentationなど)
  • Go言語の古いコミット履歴と関連する議論(Goのメーリングリストやコードレビューシステムなど)