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

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

このコミットは、Go言語の標準ライブラリである net/http パッケージ内のテストユーティリティ z_last_test.go に関連する変更です。具体的には、テスト実行時にゴルーチンリークを検出する際に、特定の「面白くない(uninteresting)」ゴルーチンを無視するようフィルタリング条件を拡張しています。これにより、GOTRACEBACK=2 環境変数設定時にのみ表示される、デバッグやテストの文脈では通常考慮不要な内部的なゴルーチンが、誤ってリークとして報告されるのを防ぎます。

コミット

commit df885e70d7eea5b421310ebd863423c1ed1a191b
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date:   Fri Mar 29 08:30:28 2013 -0700

    net/http: ignore more uninteresting goroutines
    
    These only show up if GOTRACEBACK=2
    
    Update #5005
    
    R=golang-dev, fullung
    CC=golang-dev
    https://golang.org/cl/8156044

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

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

元コミット内容

net/http: ignore more uninteresting goroutines

このコミットは、GOTRACEBACK=2 が設定されている場合にのみ表示される、テストの文脈では重要ではないゴルーチンをさらに無視するようにします。

Issue #5005 を更新します。

変更の背景

Go言語のテストスイートでは、テスト実行後に予期せぬゴルーチンが残っていないか(ゴルーチンリークがないか)をチェックするメカニズムがしばしば組み込まれています。これは、リソースの不適切な解放やデッドロックの可能性を示す重要な指標となるためです。

しかし、特定のデバッグ設定、特に GOTRACEBACK=2 が設定されている場合、Goランタイム自体が生成する内部的なゴルーチン(例えば、ガベージコレクションに関連するものや、ゴルーチン終了処理に関連するもの)がスタックトレースに現れることがあります。これらのゴルーチンは、アプリケーションのロジックによって生成されたものではなく、Goランタイムの正常な動作の一部であるため、ゴルーチンリークとして誤って検出されるべきではありません。

このコミットは、まさにこの問題に対処するために行われました。Issue #5005(特にコメント28)で議論されたように、GOTRACEBACK=2 環境下でテストを実行すると、これらの「面白くない」ゴルーチンがテストのゴルーチンリーク検出ロジックによって捕捉され、テストが失敗する原因となっていました。この変更は、これらの誤検出を排除し、テストの信頼性を向上させることを目的としています。

前提知識の解説

ゴルーチン (Goroutine)

Go言語におけるゴルーチンは、軽量な実行スレッドのようなものです。Goランタイムによって管理され、OSのスレッドよりもはるかに少ないメモリで多数を同時に実行できます。並行処理を実現するためのGoの基本的な構成要素です。

スタックトレース (Stack Trace)

プログラムの実行中にエラーや特定のイベントが発生した際に、その時点での関数呼び出しの履歴(コールスタック)を一覧表示したものです。デバッグ時に問題の発生源を特定するために非常に役立ちます。

GOTRACEBACK 環境変数

GOTRACEBACK はGoプログラムの実行時に設定できる環境変数で、パニック発生時のスタックトレースの出力レベルを制御します。

  • GOTRACEBACK=0: スタックトレースを出力しない。
  • GOTRACEBACK=1 (デフォルト): 簡潔なスタックトレースを出力する。
  • GOTRACEBACK=2: すべてのゴルーチンのスタックトレースを出力する。これは、デバッグ時にすべてのゴルーチンの状態を詳細に調査したい場合に有用です。
  • GOTRACEBACK=crash: スタックトレースを出力し、クラッシュダンプを生成する(OSに依存)。
  • GOTRACEBACK=all: すべてのゴルーチンのスタックトレースを出力し、デッドロック検出を無効にする。

このコミットでは、GOTRACEBACK=2 の設定が特に重要です。この設定により、通常は隠されているGoランタイム内部のゴルーチンもスタックトレースに現れるため、テストのゴルーチンリーク検出ロジックがそれらを誤って「リーク」と判断してしまう問題が発生していました。

ガベージコレクション (Garbage Collection, GC)

Go言語は自動メモリ管理(ガベージコレクション)を採用しています。プログラムが不要になったメモリを自動的に解放する仕組みです。ガベージコレクタはバックグラウンドで動作し、その過程で内部的なゴルーチンを生成することがあります。

net/http パッケージ

Go言語の標準ライブラリの一部で、HTTPクライアントとサーバーの実装を提供します。ウェブアプリケーションやAPIサーバーを構築する際に広く利用されます。

技術的詳細

このコミットの技術的な核心は、src/pkg/net/http/z_last_test.go ファイル内の interestingGoroutines() 関数にあります。この関数は、テスト終了時に存在するゴルーチンのスタックトレースを分析し、テストの文脈で「興味深い」(つまり、リークの可能性がある)ゴルーチンのみをフィルタリングして返します。

変更前は、この関数は net.startServertesting.RunTestscloseWriteAndWaittesting.Main といった、テストフレームワークやHTTPサーバーの起動に関連するゴルーチンを無視していました。これらはテストの正常な動作の一部であり、リークではないためです。

今回の変更では、以下の3つのパターンが追加で無視されるようになりました。

  1. runtime.goexit
  2. created by runtime.gc
  3. runtime.MHeap_Scavenger

これらのパターンは、GOTRACEBACK=2 が設定されている場合にのみスタックトレースに現れる、Goランタイムの内部的なゴルーチンに関連しています。

  • runtime.goexit: ゴルーチンが正常に終了する際の内部的な処理に関連するスタックフレームです。
  • created by runtime.gc: ガベージコレクタが生成する内部ゴルーチンに関連します。ガベージコレクションはバックグラウンドで動作し、そのために一時的なゴルーチンを使用することがあります。
  • runtime.MHeap_Scavenger: Goのメモリヒープ管理の一部であるスカベンジャー(メモリの再利用や解放を行うプロセス)に関連するゴルーチンです。これもランタイムの内部動作です。

これらのゴルーチンは、アプリケーションコードのバグによるリークではなく、Goランタイムの正常な動作の一部であるため、テストのゴルーチンリーク検出からは除外されるべきです。この変更により、GOTRACEBACK=2 環境下でのテストの誤検出が解消され、より正確なゴルーチンリーク検出が可能になります。

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

変更は src/pkg/net/http/z_last_test.go ファイルの interestingGoroutines() 関数内で行われました。

--- a/src/pkg/net/http/z_last_test.go
+++ b/src/pkg/net/http/z_last_test.go
@@ -27,7 +27,11 @@ func interestingGoroutines() (gs []string) {
 			strings.Contains(stack, "created by net.startServer") ||
 			strings.Contains(stack, "created by testing.RunTests") ||
 			strings.Contains(stack, "closeWriteAndWait") ||
-			strings.Contains(stack, "testing.Main(\") {
+			strings.Contains(stack, "testing.Main(\") ||
+			// These only show up with GOTRACEBACK=2; Issue 5005 (comment 28)
+			strings.Contains(stack, "runtime.goexit") ||
+			strings.Contains(stack, "created by runtime.gc") ||
+			strings.Contains(stack, "runtime.MHeap_Scavenger") {
 			continue
 		}
 		gs = append(gs, stack)

コアとなるコードの解説

interestingGoroutines() 関数は、現在実行中のすべてのゴルーチンのスタックトレースを取得し、それらを1つずつループ処理します。各スタックトレースに対して、strings.Contains() 関数を使用して特定の文字列パターンが含まれているかをチェックします。

変更前は、以下のパターンが含まれるスタックトレースは「面白くない」と判断され、結果リスト gs に追加されずにスキップされていました。

  • created by net.startServer
  • created by testing.RunTests
  • closeWriteAndWait
  • testing.Main(

今回のコミットでは、この条件式に以下の3つの || (OR) 条件が追加されました。

  • strings.Contains(stack, "runtime.goexit")
  • strings.Contains(stack, "created by runtime.gc")
  • strings.Contains(stack, "runtime.MHeap_Scavenger")

これにより、これらの文字列を含むスタックトレースも「面白くない」ゴルーチンとして扱われ、ゴルーチンリーク検出の対象から除外されるようになりました。コメント // These only show up with GOTRACEBACK=2; Issue 5005 (comment 28) は、この変更が GOTRACEBACK=2 設定時の特定の挙動と、関連するIssue #5005の議論に基づいていることを明確に示しています。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメントやソースコード
  • Go言語のIssueトラッカー
  • Go言語のGerrit Code Reviewシステム
  • GOTRACEBACK 環境変数に関するGoのドキュメントやブログ記事# [インデックス 16004] ファイルの概要

このコミットは、Go言語の標準ライブラリである net/http パッケージ内のテストユーティリティ z_last_test.go に関連する変更です。具体的には、テスト実行時にゴルーチンリークを検出する際に、特定の「面白くない(uninteresting)」ゴルーチンを無視するようフィルタリング条件を拡張しています。これにより、GOTRACEBACK=2 環境変数設定時にのみ表示される、デバッグやテストの文脈では通常考慮不要な内部的なゴルーチンが、誤ってリークとして報告されるのを防ぎます。

コミット

commit df885e70d7eea5b421310ebd863423c1ed1a191b
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date:   Fri Mar 29 08:30:28 2013 -0700

    net/http: ignore more uninteresting goroutines
    
    These only show up if GOTRACEBACK=2
    
    Update #5005
    
    R=golang-dev, fullung
    CC=golang-dev
    https://golang.org/cl/8156044

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

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

元コミット内容

net/http: ignore more uninteresting goroutines

このコミットは、GOTRACEBACK=2 が設定されている場合にのみ表示される、テストの文脈では重要ではないゴルーチンをさらに無視するようにします。

Issue #5005 を更新します。

変更の背景

Go言語のテストスイートでは、テスト実行後に予期せぬゴルーチンが残っていないか(ゴルーチンリークがないか)をチェックするメカニズムがしばしば組み込まれています。これは、リソースの不適切な解放やデッドロックの可能性を示す重要な指標となるためです。

しかし、特定のデバッグ設定、特に GOTRACEBACK=2 が設定されている場合、Goランタイム自体が生成する内部的なゴルーチン(例えば、ガベージコレクションに関連するものや、ゴルーチン終了処理に関連するもの)がスタックトレースに現れることがあります。これらのゴルーチンは、アプリケーションのロジックによって生成されたものではなく、Goランタイムの正常な動作の一部であるため、ゴルーチンリークとして誤って検出されるべきではありません。

このコミットは、まさにこの問題に対処するために行われました。Issue #5005(特にコメント28)で議論されたように、GOTRACEBACK=2 環境下でテストを実行すると、これらの「面白くない」ゴルーチンがテストのゴルーチンリーク検出ロジックによって捕捉され、テストが失敗する原因となっていました。この変更は、これらの誤検出を排除し、テストの信頼性を向上させることを目的としています。

前提知識の解説

ゴルーチン (Goroutine)

Go言語におけるゴルーチンは、軽量な実行スレッドのようなものです。Goランタイムによって管理され、OSのスレッドよりもはるかに少ないメモリで多数を同時に実行できます。並行処理を実現するためのGoの基本的な構成要素です。

スタックトレース (Stack Trace)

プログラムの実行中にエラーや特定のイベントが発生した際に、その時点での関数呼び出しの履歴(コールスタック)を一覧表示したものです。デバッグ時に問題の発生源を特定するために非常に役立ちます。

GOTRACEBACK 環境変数

GOTRACEBACK はGoプログラムの実行時に設定できる環境変数で、パニック発生時のスタックトレースの出力レベルを制御します。

  • GOTRACEBACK=0: スタックトレースを出力しない。
  • GOTRACEBACK=1 (デフォルト): 簡潔なスタックトレースを出力する。
  • GOTRACEBACK=2: すべてのゴルーチンのスタックトレースを出力する。これは、デバッグ時にすべてのゴルーチンの状態を詳細に調査したい場合に有用です。
  • GOTRACEBACK=crash: スタックトレースを出力し、クラッシュダンプを生成する(OSに依存)。
  • GOTRACEBACK=all: すべてのゴルーチンのスタックトレースを出力し、デッドロック検出を無効にする。

このコミットでは、GOTRACEBACK=2 の設定が特に重要です。この設定により、通常は隠されているGoランタイム内部のゴルーチンもスタックトレースに現れるため、テストのゴルーチンリーク検出ロジックがそれらを誤って「リーク」と判断してしまう問題が発生していました。

ガベージコレクション (Garbage Collection, GC)

Go言語は自動メモリ管理(ガベージコレクション)を採用しています。プログラムが不要になったメモリを自動的に解放する仕組みです。ガベージコレクタはバックグラウンドで動作し、その過程で内部的なゴルーチンを生成することがあります。

net/http パッケージ

Go言語の標準ライブラリの一部で、HTTPクライアントとサーバーの実装を提供します。ウェブアプリケーションやAPIサーバーを構築する際に広く利用されます。

技術的詳細

このコミットの技術的な核心は、src/pkg/net/http/z_last_test.go ファイル内の interestingGoroutines() 関数にあります。この関数は、テスト終了時に存在するゴルーチンのスタックトレースを分析し、テストの文脈で「興味深い」(つまり、リークの可能性がある)ゴルーチンのみをフィルタリングして返します。

変更前は、この関数は net.startServertesting.RunTestscloseWriteAndWaittesting.Main といった、テストフレームワークやHTTPサーバーの起動に関連するゴルーチンを無視していました。これらはテストの正常な動作の一部であり、リークではないためです。

今回の変更では、以下の3つのパターンが追加で無視されるようになりました。

  1. runtime.goexit
  2. created by runtime.gc
  3. runtime.MHeap_Scavenger

これらのパターンは、GOTRACEBACK=2 が設定されている場合にのみスタックトレースに現れる、Goランタイムの内部的なゴルーチンに関連しています。

  • runtime.goexit: ゴルーチンが正常に終了する際の内部的な処理に関連するスタックフレームです。
  • created by runtime.gc: ガベージコレクタが生成する内部ゴルーチンに関連します。ガベージコレクションはバックグラウンドで動作し、そのために一時的なゴルーチンを使用することがあります。
  • runtime.MHeap_Scavenger: Goのメモリヒープ管理の一部であるスカベンジャー(メモリの再利用や解放を行うプロセス)に関連するゴルーチンです。これもランタイムの内部動作です。

これらのゴルーチンは、アプリケーションコードのバグによるリークではなく、Goランタイムの正常な動作の一部であるため、テストのゴルーチンリーク検出からは除外されるべきです。この変更により、GOTRACEBACK=2 環境下でのテストの誤検出が解消され、より正確なゴルーチンリーク検出が可能になります。

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

変更は src/pkg/net/http/z_last_test.go ファイルの interestingGoroutines() 関数内で行われました。

--- a/src/pkg/net/http/z_last_test.go
+++ b/src/pkg/net/http/z_last_test.go
@@ -27,7 +27,11 @@ func interestingGoroutines() (gs []string) {
 			strings.Contains(stack, "created by net.startServer") ||
 			strings.Contains(stack, "created by testing.RunTests") ||
 			strings.Contains(stack, "closeWriteAndWait") ||
-			strings.Contains(stack, "testing.Main(\") {
+			strings.Contains(stack, "testing.Main(\") ||
+			// These only show up with GOTRACEBACK=2; Issue 5005 (comment 28)
+			strings.Contains(stack, "runtime.goexit") ||
+			strings.Contains(stack, "created by runtime.gc") ||
+			strings.Contains(stack, "runtime.MHeap_Scavenger") {
 			continue
 		}
 		gs = append(gs, stack)

コアとなるコードの解説

interestingGoroutines() 関数は、現在実行中のすべてのゴルーチンのスタックトレースを取得し、それらを1つずつループ処理します。各スタックトレースに対して、strings.Contains() 関数を使用して特定の文字列パターンが含まれているかをチェックします。

変更前は、以下のパターンが含まれるスタックトレースは「面白くない」と判断され、結果リスト gs に追加されずにスキップされていました。

  • created by net.startServer
  • created by testing.RunTests
  • closeWriteAndWait
  • testing.Main(

今回のコミットでは、この条件式に以下の3つの || (OR) 条件が追加されました。

  • strings.Contains(stack, "runtime.goexit")
  • strings.Contains(stack, "created by runtime.gc")
  • strings.Contains(stack, "runtime.MHeap_Scavenger")

これにより、これらの文字列を含むスタックトレースも「面白くない」ゴルーチンとして扱われ、ゴルーチンリーク検出の対象から除外されるようになりました。コメント // These only show up with GOTRACEBACK=2; Issue 5005 (comment 28) は、この変更が GOTRACEBACK=2 設定時の特定の挙動と、関連するIssue #5005の議論に基づいていることを明確に示しています。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメントやソースコード
  • Go言語のIssueトラッカー
  • Go言語のGerrit Code Reviewシステム
  • GOTRACEBACK 環境変数に関するGoのドキュメントやブログ記事