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

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

このコミットは、Go言語のデバッグシンボルテーブルを扱うdebug/gosymパッケージ内のテストファイルpclntab_test.goに対する変更です。具体的には、テストで使用されるバイナリファイルpclinetestのパス指定に関する修正が行われています。

コミット

commit c38173bcbd2f51d7801d834d3a8a34f75fc1605c
Author: Keith Randall <khr@golang.org>
Date:   Fri Jul 19 12:31:42 2013 -0700

    debug/gosym: put pclinetest file in temporary directory
    where it belongs.
    
    R=rsc
    CC=golang-dev
    https://golang.org/cl/11596043

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

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

元コミット内容

debug/gosym: put pclinetest file in temporary directory
where it belongs.

R=rsc
CC=golang-dev
https://golang.org/cl/11596043

変更の背景

このコミットの背景には、テスト実行時のファイル管理のベストプラクティスがあります。テスト中に生成される一時ファイルは、テストが完了した後にクリーンアップされるべきであり、システムの他の部分に影響を与えないように一時ディレクトリに配置されるのが一般的です。

pclinetestというファイルは、debug/gosymパッケージのテスト、特にGoのプログラムカウンタ(PC)と行番号(line number)のマッピング情報(pclnテーブル)のテストのために生成されるバイナリファイルです。以前のコードでは、このpclinetestバイナリが一時ディレクトリのパスに結合された後、そのパスが上書きされて単に"pclinetest"となっていました。これは、テストが実行されるディレクトリに直接このバイナリが生成されることを意味し、テスト環境を汚染したり、予期せぬファイル衝突を引き起こす可能性がありました。

このコミットは、pclinetestバイナリが意図通り一時ディレクトリ内に生成されるように修正し、テストのクリーンアップと独立性を確保することを目的としています。

前提知識の解説

Go言語のdebug/gosymパッケージ

debug/gosymパッケージは、Goプログラムのデバッグ情報、特にシンボルテーブルとプログラムカウンタ-行番号テーブル(PC-Line Table、通称pclnテーブル)を解析するための機能を提供します。

  • シンボルテーブル: プログラム内の関数、変数、型などの名前と、それらがメモリ上のどこに配置されているかの情報(アドレス)をマッピングしたものです。デバッガが関数名や変数名を使ってコードの実行を追跡するために不可欠です。
  • PC-Line Table (pclnテーブル): プログラムカウンタ(PC、現在実行中の命令のアドレス)とソースコードの行番号をマッピングしたテーブルです。これにより、デバッガは実行中のコードがソースファイルのどの行に対応するかを特定できます。スタックトレースの生成や、エラー発生時の正確な位置特定に利用されます。

debug/gosymパッケージは、Goのバイナリファイルからこれらの情報を抽出し、Goプログラムのデバッグやプロファイリングツールが内部的に利用します。

pclinetest

pclinetestは、debug/gosymパッケージのテストで使用される特別なバイナリファイルです。このファイルは、Goのアセンブラ(go tool 6aなど)とリンカ(go tool 6lなど)を使用して、特定のpclinetest.asm(アセンブリコード)から生成されます。その目的は、pclnテーブルの解析機能が正しく動作するかどうかを検証することです。つまり、特定のPCアドレスが正しいソースコードの行番号にマッピングされるかをテストするために、意図的に制御されたpcln情報を持つバイナリを生成し、それをdebug/gosymで解析します。

一時ディレクトリの利用

ソフトウェア開発において、テスト中に一時的なファイルやディレクトリを作成することはよくあります。これらのファイルはテストの実行に必要なデータを含んでいたり、テスト結果を保存したりするために使われます。しかし、これらのファイルがテスト実行後に残ってしまうと、システムのディスクスペースを消費したり、後続のテスト実行に影響を与えたりする可能性があります。

このため、一時ファイルは通常、オペレーティングシステムが提供する一時ディレクトリ(例: Linux/macOSの/tmp、Windowsの%TEMP%)内に作成されます。Go言語では、os.TempDir()関数で一時ディレクトリのパスを取得でき、ioutil.TempDir()ioutil.TempFile()(Go 1.16以降はos.MkdirTemp()os.CreateTemp())で安全に一時ディレクトリや一時ファイルを作成できます。テストフレームワークでは、テストのセットアップ(setUp)で一時ディレクトリを作成し、テストのティアダウン(tearDown)でそのディレクトリを削除するパターンが一般的です。

技術的詳細

このコミットは、src/pkg/debug/gosym/pclntab_test.goファイル内の1行の変更です。

変更前のコードでは、pclinetestBinaryという変数が、まずfilepath.Join(pclineTempDir, "pclinetest")によって一時ディレクトリのパスとファイル名が結合された正しいパスに設定されていました。しかし、その直後にpclinetestBinary = "pclinetest"という行があり、この正しいパスが上書きされてしまっていました。これにより、pclinetestバイナリは一時ディレクトリではなく、テストが実行されるカレントディレクトリに生成されていました。

変更後のコードでは、このpclinetestBinary = "pclinetest"という行が削除されています。これにより、pclinetestBinaryは常にfilepath.Join(pclineTempDir, "pclinetest")で設定された一時ディレクトリ内のパスを指すようになり、テストによって生成されるバイナリが適切に一時ディレクトリに配置されるようになります。

この修正は、テストの実行環境のクリーンさを保ち、テストの独立性と信頼性を向上させるためのものです。一時ディレクトリにファイルを置くことで、テストが終了した際にそのディレクトリを簡単に削除でき、システムに不要なファイルが残ることを防ぎます。

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

--- a/src/pkg/debug/gosym/pclntab_test.go
+++ b/src/pkg/debug/gosym/pclntab_test.go
@@ -49,7 +49,6 @@ func dotest(self bool) bool {
 	// the resulting binary looks like it was built from pclinetest.s,
 	// but we have renamed it to keep it away from the go tool.
 	pclinetestBinary = filepath.Join(pclineTempDir, "pclinetest")
-	pclinetestBinary = "pclinetest"
 	command := fmt.Sprintf("go tool 6a -o %s.6 pclinetest.asm && go tool 6l -H linux -E main -o %s %s.6",
 		pclinetestBinary, pclinetestBinary, pclinetestBinary)
 	cmd := exec.Command("sh", "-c", command)

コアとなるコードの解説

変更されたのはsrc/pkg/debug/gosym/pclntab_test.goファイルの以下の部分です。

	pclinetestBinary = filepath.Join(pclineTempDir, "pclinetest")
	// pclinetestBinary = "pclinetest" // この行が削除された
  • pclinetestBinary: テストで生成されるpclinetestバイナリのパスを保持する変数です。
  • pclineTempDir: テストのために作成された一時ディレクトリのパスです。
  • filepath.Join(pclineTempDir, "pclinetest"): pclineTempDirとファイル名"pclinetest"を結合し、OSに応じた正しいパス(例: /tmp/go-test-XXXXX/pclinetest)を生成します。

削除された行は、pclinetestBinaryに一時ディレクトリ内のパスが設定された直後に、その値を単なるファイル名"pclinetest"で上書きしていました。この上書きによって、バイナリは一時ディレクトリではなく、テスト実行時のカレントディレクトリに作成されていました。この行を削除することで、pclinetestBinaryは常に一時ディレクトリ内の正しいパスを指すようになり、テストの副作用が適切に管理されるようになりました。

この修正は、コードの論理的な意図(一時ディレクトリにファイルを置く)と実際の挙動を一致させるための、シンプルながらも重要なバグ修正です。

関連リンク

参考にした情報源リンク