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

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

このコミットは、Go言語のランタイムプロファイリングツールである pprof における、NetBSDおよびOpenBSD環境でのCPUプロファイルの不正確さに関する以前の変更(CL 12787044 / ed695cdf962b)を元に戻すものです。これは、これらのOSでのプロファイリングの問題が依然として解決されていないことを示しています。

コミット

commit ba14974e070734b3eb1a2b58097675c13978c1af
Author: Russ Cox <rsc@golang.org>
Date:   Tue Aug 13 23:33:49 2013 +0400

    undo CL 12787044 / ed695cdf962b
    
    The NetBSD and OpenBSD failures are apparently real,
    not due to the test bug fixed in 100b9fc0c46f.
    
    ««« original CL description
    runtime/pprof: test netbsd and openbsd again
    
    Maybe these will work now.
    
    R=golang-dev, dvyukov, bradfitz
    CC=golang-dev
    https://golang.org/cl/12787044
    »»»
    
    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/12873043
---\n src/pkg/runtime/pprof/pprof.go      | 2 +-\n src/pkg/runtime/pprof/pprof_test.go | 6 +++---\n 2 files changed, 4 insertions(+), 4 deletions(-)\n

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

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

元コミット内容

元となったコミット (CL 12787044 / ed695cdf962b) は、runtime/pprof パッケージがNetBSDとOpenBSD環境で正しく動作するかどうかを再テストすることを目的としていました。コミットメッセージの「Maybe these will work now. (もしかしたら今なら動くかもしれない)」という記述から、以前からこれらのOSでの pprof の問題が認識されており、何らかの変更(おそらくテストの修正など)によって改善された可能性を期待して再試行されたことが伺えます。

変更の背景

このコミットは、以前のCL 12787044 / ed695cdf962b を「元に戻す (undo)」ものです。その理由は、NetBSDとOpenBSDでの pprof の失敗が、以前に修正されたテストのバグ (100b9fc0c46f) によるものではなく、「明らかに現実の (apparently real)」問題であったためです。

Goの pprof ツールは、OS X (現在のmacOS)、NetBSD、OpenBSDといった一部のOSでCPUプロファイルが不正確になるという既知の問題を抱えていました。これは、Go issue 6047 で詳細に議論されています。特に、プロファイリングシグナルが間違ったスレッドに配信されることが原因で、マルチスレッドのCPUプロファイルが誤った結果を出すことがありました。NetBSDとOpenBSDはOS Xとコードベースを共有している部分があるため、同様の問題を抱えていました。

以前のCLは、これらのOSでの pprof の動作が改善されたことを期待してテストを再有効化しましたが、実際には問題が解決されていなかったため、このコミットでその変更が取り消され、これらのOSでの pprof の不正確さが再び明示的に認識される状態に戻されました。

前提知識の解説

  • Go言語の pprof: pprof はGo言語の標準ライブラリに含まれるプロファイリングツールです。CPU使用率、メモリ割り当て、ゴルーチン、ブロック、ミューテックス競合など、様々な種類のプロファイルを収集し、プログラムのパフォーマンスボトルネックを特定するのに役立ちます。CPUプロファイルは、プログラムがCPU時間をどこで消費しているかを関数レベルで可視化します。
  • CPUプロファイリングの仕組み: CPUプロファイリングは通常、一定の間隔(例えば10ミリ秒ごと)でプログラムの実行を一時停止し、その時点でのコールスタック(どの関数がどの関数を呼び出しているか)を記録することで行われます。これにより、CPU時間を多く消費している関数やコードパスを特定できます。
  • シグナルハンドリング: Unix系OSでは、シグナルはプロセスに対して非同期にイベントを通知するメカニズムです。プロファイリングでは、タイマーシグナルなどを用いて定期的にプロファイリング情報を収集することが一般的です。しかし、マルチスレッド環境では、シグナルが意図しないスレッドに配信されることがあり、これがプロファイリングの不正確さにつながることがあります。
  • /proc/self/maps とメモリマップ: Linuxシステムでは、/proc/self/maps ファイルは現在のプロセスの仮想メモリマップに関する情報を提供します。これは、実行可能ファイルや共有ライブラリがメモリのどこにロードされているかを知るために pprof のようなツールが利用します。しかし、NetBSDやOpenBSDのような他のUnix系OSでは、このファイルが存在しないか、異なるメカニズム(例: sysctl)で同様の情報を提供します。pprof がLinux固有の /proc/self/maps に依存している場合、他のOSでの動作に問題が生じます。
  • Go issue 6047: このissueは、Goの pprof がOS X、NetBSD、OpenBSDで不正確なプロファイルを出力する問題について追跡しています。主な原因は、プロファイリングシグナルが間違ったスレッドに配信されることと、メモリマップ情報の取得方法がOS間で異なることでした。

技術的詳細

このコミットが元に戻した問題の技術的詳細は、主に以下の点に集約されます。

  1. シグナル配信の不正確さ: OS X、NetBSD、OpenBSDでは、CPUプロファイリングのために使用されるシグナル(例えば SIGPROF)が、プロファイリング対象のゴルーチンが実行されているスレッドではなく、別のスレッドに配信されることがありました。これにより、収集されるコールスタック情報が、実際にCPU時間を消費しているコードパスと一致せず、プロファイルが不正確になります。
  2. /proc/self/maps への依存: pprof は、プロファイルされたアドレスをシンボル名(関数名など)に解決するために、プロセスのメモリマップ情報を必要とします。Linuxでは /proc/self/maps を読み取ることでこの情報を取得できますが、NetBSDやOpenBSDには同等のファイルシステムインターフェースがありません。これらのOSでは sysctl のような異なるシステムコールを通じてメモリマップ情報を取得する必要があります。pprof がLinux固有の実装に依存していたため、他のOSではシンボル解決が正しく行えず、プロファイルが機能しないか、不完全なものになりました。
  3. テストの限界: 以前のCLは、テストのバグが修正されたことで、これらのOSでの pprof が動作するようになったと期待しましたが、実際のプロファイリングの根本的な問題は解決されていませんでした。これは、テストが特定のシナリオしかカバーしておらず、実際の複雑なマルチスレッド環境でのプロファイリングの不正確さを完全に捉えきれていなかったことを示唆しています。

このコミットは、これらの技術的な課題が依然として存在することを認め、一時的に有効化されたテストを無効に戻すことで、既知の制限を明確にしました。

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

このコミットでは、以下の2つのファイルが変更されています。

  1. src/pkg/runtime/pprof/pprof.go
  2. src/pkg/runtime/pprof/pprof_test.go

それぞれの変更内容は以下の通りです。

src/pkg/runtime/pprof/pprof.go

--- a/src/pkg/runtime/pprof/pprof.go
+++ b/src/pkg/runtime/pprof/pprof.go
@@ -20,7 +20,7 @@ import (
 	"text/tabwriter"
 )
 
-// BUG(rsc): Profiles are incomplete and inaccuate on OS X.
+// BUG(rsc): Profiles are incomplete and inaccuate on NetBSD, OpenBSD, and OS X.
 // See http://golang.org/issue/6047 for details.
 
 // A Profile is a collection of stack traces showing the call sequences

src/pkg/runtime/pprof/pprof_test.go

--- a/src/pkg/runtime/pprof/pprof_test.go
+++ b/src/pkg/runtime/pprof/pprof_test.go
@@ -175,9 +175,9 @@ func TestCPUProfileWithFork(t *testing.T) {
 
 // Operating systems that are expected to fail the tests. See issue 6047.
 var badOS = map[string]bool{
-\t"darwin": true,\n-\t//\"netbsd\":  true,\n-\t//\"openbsd\": true,\n+\t"darwin":  true,\n+\t"netbsd":  true,\n+\t"openbsd": true,\n }\n 
 func TestBlockProfile(t *testing.T) {

コアとなるコードの解説

  1. src/pkg/runtime/pprof/pprof.go の変更:

    • // BUG(rsc): Profiles are incomplete and inaccuate on OS X. というコメントが、 // BUG(rsc): Profiles are incomplete and inaccuate on NetBSD, OpenBSD, and OS X. に変更されました。
    • これは、pprof のプロファイルが不完全または不正確であるという既知のバグが、OS Xだけでなく、NetBSDとOpenBSDにも適用されることを明示的に示すための変更です。以前のCLでこれらのOSのテストが有効化されたことで、問題が解決されたかのように見えましたが、実際にはそうではなかったため、このコメントを修正して現状を正確に反映させています。
  2. src/pkg/runtime/pprof/pprof_test.go の変更:

    • badOS マップは、pprof のテストが失敗すると予想されるオペレーティングシステムを定義しています。
    • 以前のバージョンでは、"netbsd""openbsd" のエントリがコメントアウトされていました。これは、以前のCLがこれらのOSでのテストを再有効化しようとしたためです。
    • このコミットでは、"netbsd": true,"openbsd": true, のコメントが解除され、これらのOSが再び badOS マップに含まれるようになりました。
    • これにより、NetBSDとOpenBSD上での pprof テストは、既知のバグのために失敗することが予想されるため、スキップされるか、特定の失敗が許容されるようになります。これは、これらのOSでの pprof の問題が依然として解決されていないことをコードレベルで反映しています。

これらの変更は、Goの pprof が特定のOSで抱えるプロファイリングの課題が、この時点ではまだ解決されていないという現実を反映し、コードベースとドキュメントの両方でその状態を明確にするためのものです。

関連リンク

参考にした情報源リンク