[インデックス 19324] ファイルの概要
このコミットは、Go言語の cmd/objdump
ツールがWindowsのPE (Portable Executable) 形式の実行ファイルを正しく処理できるようにするための重要な改善を導入しています。具体的には、Goバイナリに埋め込まれている .gosymtab
(Goシンボルテーブル) および .gopclntab
(Go PC-Lineテーブル) セクションの読み込みロジックが、PEファイル形式の特性に合わせて修正されました。これにより、Windows上でビルドされたGoの実行ファイルに対しても objdump
が正確なシンボル情報やデバッグ情報を表示できるようになります。また、この変更を検証するために、新しいテストファイル objdump_test.go
が追加されています。
コミット
commit 20aa947c56bd34d2c87b616bffbc4535a62ab778
Author: Alex Brainman <alex.brainman@gmail.com>
Date: Mon May 12 17:00:57 2014 +1000
cmd/objdump: works with windows pe executables now
Most code is copy from addr2line change 01dd67e5827f
Update #7406
Fixes #7937
LGTM=iant
R=golang-codereviews, iant, 0intro
CC=golang-codereviews
https://golang.org/cl/95090044
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/20aa947c56bd34d2c87b616bffbc4535a62ab778
元コミット内容
cmd/objdump: works with windows pe executables now
Most code is copy from addr2line change 01dd67e5827f
Update #7406
Fixes #7937
LGTM=iant
R=golang-codereviews, iant, 0intro
CC=golang-codereviews
https://golang.org/cl/95090044
変更の背景
Go言語の objdump
ツールは、コンパイルされたGoプログラムのバイナリを解析し、逆アセンブルされたコードにシンボル名やソースコードの行番号などのデバッグ情報を付加して表示する役割を担っています。これは、プログラムの動作を詳細に理解したり、パフォーマンスの問題を特定したり、クラッシュ時のスタックトレースを解析したりする上で不可欠なツールです。
このコミットが導入される以前は、objdump
がWindowsオペレーティングシステムで生成されるPE形式の実行ファイルを完全にサポートしていませんでした。特に、Goコンパイラがバイナリに埋め込む .gosymtab
(Goシンボルテーブル) や .gopclntab
(Go PC-Lineテーブル) といったGo特有のカスタムセクションから、必要な情報を正確に抽出することが困難でした。このため、Windows環境でビルドされたGoの実行ファイルに対して objdump
を実行しても、期待される詳細なデバッグ情報やシンボル情報が得られず、デバッグや解析作業が著しく妨げられるという問題がありました。
コミットメッセージに記載されている Update #7406
および Fixes #7937
は、これらの問題報告に対応するものであると推測されます。これらの具体的なissueは現在のGoのissueトラッカーでは直接特定できませんでしたが、objdump
がWindows PEバイナリを適切に扱えないというユーザーからのフィードバックやバグレポートが存在したことを示唆しています。
また、「Most code is copy from addr2line change 01dd67e5827f」という記述は、addr2line
ツール(プログラムカウンタのアドレスからソースコードのファイル名と行番号を解決するツール)がPEファイルを扱うために既に導入していたロジックが、objdump
にも適用されたことを示しています。これは、Goツールチェイン内で同様の機能が必要とされる場合に、既存の堅牢なコードを再利用し、ツール間の一貫性を保つというGo開発における一般的なプラクティスを反映しています。
前提知識の解説
このコミットの変更内容を深く理解するためには、以下の技術的な概念を把握しておく必要があります。
-
Goの
objdump
ツール: Go言語の標準ツールセットに含まれるコマンドラインユーティリティです。Goプログラムのコンパイル済みバイナリ(実行ファイルやライブラリ)を解析し、その内容を人間が読める形式で表示します。主な機能は以下の通りです。- 逆アセンブル: 機械語命令をアセンブリ言語に変換して表示します。
- シンボル情報の表示: 関数名、変数名、グローバルデータなどのシンボルとそのアドレスを表示します。
- PC-Line情報の表示: プログラムカウンタ(命令アドレス)と、対応するソースコードのファイル名および行番号のマッピングを表示します。これにより、逆アセンブルされたコードがソースコードのどの部分に対応するのかを理解できます。
objdump
は、デバッグ、パフォーマンスプロファイリング、バイナリ解析、セキュリティ監査など、様々な場面でGoプログラムの内部構造を調査するために利用されます。
-
PE (Portable Executable) 形式: Microsoft Windowsオペレーティングシステムで使用される実行可能ファイル、オブジェクトコード、DLL (Dynamic Link Library) などの標準的なファイル形式です。PEファイルは、以下のような主要な構造で構成されています。
- DOSヘッダ: 互換性のために残された古いDOS実行可能ファイルのヘッダ。
- PEヘッダ: ファイルがPE形式であることを示すシグネチャと、ファイルタイプ(EXE、DLLなど)、タイムスタンプ、セクション数などの情報が含まれます。
- オプションヘッダ: 実行ファイルのメモリレイアウト、エントリポイントアドレス、スタックサイズ、ヒープサイズなどの情報が含まれます。
- セクションテーブル: ファイル内の各セクション(コード、データ、リソースなど)の名前、仮想アドレス、サイズ、ファイル内のオフセット、属性などの情報が記述されます。
- セクション: 実際のコード、初期化済みデータ、未初期化データ、リソースなどが格納される領域です。Goコンパイラは、PEファイル内にGo特有の情報を格納するためのカスタムセクション(例:
.gosymtab
,.gopclntab
)を作成することがあります。
-
.gosymtab
セクション: Goコンパイラが生成するGoバイナリに含まれるカスタムセクションの一つです。このセクションには、Goプログラム内のすべてのシンボル(関数、グローバル変数、型など)に関する情報が格納されています。具体的には、シンボルの名前、アドレス、サイズ、種類(関数、データなど)といったメタデータが含まれます。デバッガやプロファイラなどのツールは、この.gosymtab
を解析することで、実行中のプログラムのアドレスを人間が理解できるシンボル名に解決し、より意味のある情報を提供します。 -
.gopclntab
セクション: Goコンパイラが生成するもう一つの重要なカスタムセクションです。PC-Lineテーブル(Program Counter-Line Table)の略で、プログラムカウンタ(CPUが現在実行している命令のアドレス)と、対応するソースコードのファイル名および行番号のマッピング情報が格納されています。Goランタイムは、パニック発生時のスタックトレース生成や、プロファイリングツールが実行パスをソースコードに紐付ける際などに、この.gopclntab
の情報を利用します。このテーブルが正しく解析できないと、スタックトレースが意味不明なアドレスの羅列になったり、デバッグ情報が失われたりします。 -
シンボルとPC-Lineテーブルの重要性: これらの情報は、ソフトウェア開発におけるデバッグと解析の根幹をなします。
- デバッグ: プログラムがクラッシュしたり、予期せぬ動作をしたりした場合に、スタックトレースから問題発生箇所のソースコード上の位置を特定するために不可欠です。
- プロファイリング: プログラムのパフォーマンスボトルネックを特定する際に、実行時間の大部分を占める関数やコード行を特定するために使用されます。
- バイナリ解析: 悪意のあるソフトウェアの解析や、リバースエンジニアリングにおいて、バイナリの機能を理解するためにシンボル情報が役立ちます。 これらの情報が正しく読み取れない場合、デバッグや解析の効率は著しく低下し、問題解決に多大な時間を要することになります。
-
debug/pe
パッケージ: Go言語の標準ライブラリに含まれるパッケージで、PEファイル形式をGoプログラムから読み込み、解析するための機能を提供します。pe.File
構造体はPEファイル全体を表し、pe.Section
構造体はPEファイル内の個々のセクション(例:.text
,.data
,.gosymtab
)を表します。このパッケージは、objdump
のようなツールがPEファイルの内容にアクセスするための基盤となります。
技術的詳細
このコミットの核心は、Windows PE形式のGoバイナリから .gosymtab
と .gopclntab
のデータを正確に抽出するための新しいメカニズムを導入した点にあります。従来の objdump
の loadTables
関数は、Unix系のELF形式やmacOSのMach-O形式のバイナリでは、セクション名(例: .gosymtab
)を直接指定してデータを読み込むことができました。しかし、PE形式では、Go特有のこれらのセクションが通常のセクションとして明確に定義されているわけではなく、特定のシンボルによってその開始と終了が示されるという特殊な方法で格納される場合があります。
この変更では、このPE形式の特性に対応するため、以下の2つの新しいヘルパー関数が導入され、既存の loadTables
関数がこれらを利用するように修正されました。
-
func findPESymbol(f *pe.File, name string) (*pe.Symbol, error)
:- 目的: PEファイル (
pe.File
型のオブジェクト) とシンボル名 (name
、文字列) を引数として受け取り、指定されたシンボルをPEファイルのシンボルテーブルから検索して返します。 - 動作:
- PEファイルの
Symbols
スライス(シンボルテーブル)を線形に走査します。 - 各シンボルの
Name
フィールドが引数name
と一致するかどうかを確認します。 - 一致するシンボルが見つかった場合、そのシンボルの
SectionNumber
が有効であること(0より大きいこと)と、そのセクション番号がPEファイルのセクションの総数を超えていないことを検証します。これにより、シンボルが有効なセクションを指していることを保証します。 - 検証が成功すれば、見つかった
pe.Symbol
オブジェクトを返します。 - シンボルが見つからない場合や、セクション番号が無効な場合は、適切なエラーを返します。
- PEファイルの
- 重要性: この関数は、GoのシンボルテーブルやPC-Lineテーブルの開始 (
symtab
,pclntab
) および終了 (esymtab
,epclntab
) を示す特定のシンボルをPEファイル内で正確に見つけるための基盤となります。これらのシンボルは、テーブルのメモリ上の範囲を定義するために使用されます。
- 目的: PEファイル (
-
func loadPETable(f *pe.File, sname, ename string) ([]byte, error)
:- 目的: PEファイル (
pe.File
) と、テーブルの開始を示すシンボル名 (sname
)、終了を示すシンボル名 (ename
) を引数として受け取り、対応するテーブルのバイトスライスを返します。 - 動作:
- まず、
findPESymbol
関数を呼び出して、sname
とename
に対応する開始シンボル (ssym
) と終了シンボル (esym
) をそれぞれ見つけます。いずれかのシンボルが見つからない場合はエラーを返します。 - 次に、開始シンボルと終了シンボルが同じセクションに存在することを確認します (
ssym.SectionNumber != esym.SectionNumber
の場合はエラー)。これは、テーブルが単一の連続したメモリ領域に格納されているという前提を満たすために重要です。 - 該当するセクション(
f.Sections[ssym.SectionNumber-1]
)を取得し、そのセクションの生データ (data
) を読み込みます。 - 最後に、セクションデータの中から、開始シンボルの値 (
ssym.Value
) から終了シンボルの値 (esym.Value
) までの範囲をスライスして、目的のテーブル(PC-Lineテーブルまたはシンボルテーブル)のバイトデータを抽出して返します。
- まず、
- 重要性: この関数は、PEファイルにおけるGo特有のテーブル(
.gosymtab
と.gopclntab
)が、シンボルによってその範囲が定義されている場合に、そのデータを正確に抽出するための汎用的なメカニズムを提供します。
- 目的: PEファイル (
loadTables
関数の変更:
既存の loadTables
関数は、Goバイナリの形式(ELF、Mach-O、PEなど)を判別し、それぞれの形式に応じた方法で .gosymtab
と .gopclntab
のデータを読み込む役割を担っています。このコミットでは、PEファイル形式の場合の処理ロジックが、新しく追加された loadPETable
関数を使用するように変更されました。
// 変更前 (抜粋)
// if sect := obj.Section(".gosymtab"); sect != nil { ... }
// if sect := obj.Section(".gopclntab"); sect != nil { ... }
// 変更後 (抜粋)
if pclntab, err = loadPETable(obj, "pclntab", "epclntab"); err != nil {
return 0, nil, nil, nil, err
}
if symtab, err = loadPETable(obj, "symtab", "esymtab"); err != nil {
return 0, nil, nil, nil, err
}
この変更により、PEファイルの場合の pclntab
と symtab
の読み込みが、直接セクション名でアクセスするのではなく、loadPETable
関数を介して行われるようになりました。これは、PEファイルがGo特有のセクションを通常のセクションとしてではなく、pclntab
と epclntab
、symtab
と esymtab
といった特定のシンボルによってその範囲を示す形で格納している場合に対応するためです。
テストファイルの追加 (objdump_test.go
):
このコミットでは、objdump
がWindows PE実行ファイルを正しく処理できるようになったことを検証するために、新しいテストファイル objdump_test.go
が追加されました。このテストは、以下の手順で objdump
の機能を検証します。
go tool nm
コマンドを使用して、テスト対象の実行ファイル(このテスト自身)からシンボル情報を取得し、特定の関数(例:cmd/objdump.TestObjDump
)のアドレスを特定します。go build
コマンドを使用して、cmd/objdump
ツールをビルドし、一時ディレクトリに実行ファイルとして出力します。- ビルドされた
objdump
実行ファイルを使用して、テスト対象の実行ファイルと特定のアドレス範囲に対してobjdump
コマンドを実行します。 objdump
の出力からソースファイル名と行番号を抽出し、それが期待される値(このテストファイル自身の特定の行番号)と一致するかどうかを検証します。- 特に、Windows環境でのパスの扱いの違い(例:
C:\path\to\file.go
のような形式)にも対応しており、クロスプラットフォームでの正確な動作を保証しています。
これらの変更により、objdump
はWindows PE形式のGoバイナリから必要なデバッグ情報を正確に抽出し、Go開発者がWindows環境でも効率的にデバッグや解析を行えるようになりました。
コアとなるコードの変更箇所
このコミットにおける主要なコード変更は、src/cmd/objdump/main.go
ファイルへの機能追加と修正、および src/cmd/objdump/objdump_test.go
ファイルの新規追加です。
src/cmd/objdump/main.go
の変更
-
loadTables
関数の修正: PEファイル形式のバイナリを処理する部分で、.gosymtab
と.gopclntab
の読み込み方法が変更されました。 変更前はセクション名を直接参照していましたが、変更後は新しく追加されたloadPETable
関数を呼び出すようになりました。--- a/src/cmd/objdump/main.go +++ b/src/cmd/objdump/main.go @@ -170,18 +170,50 @@ func loadTables(f *os.File) (textStart uint64, textData, symtab, pclntab []byte, textStart = uint64(sect.VirtualAddress) textData, _ = sect.Data() } - if sect := obj.Section(".gosymtab"); sect != nil { - if symtab, err = sect.Data(); err != nil { - return 0, nil, nil, nil, err - } - } - if sect := obj.Section(".gopclntab"); sect != nil { - if pclntab, err = sect.Data(); err != nil { - return 0, nil, nil, nil, err - } - } + if pclntab, err = loadPETable(obj, "pclntab", "epclntab"); err != nil { + return 0, nil, nil, nil, err + } + if symtab, err = loadPETable(obj, "symtab", "esymtab"); err != nil { + return 0, nil, nil, nil, err + } return textStart, textData, symtab, pclntab, nil }
-
findPESymbol
関数の新規追加: PEファイルから特定の名前のシンボルを検索するためのヘルパー関数が追加されました。--- a/src/cmd/objdump/main.go +++ b/src/cmd/objdump/main.go @@ -193,3 +225,35 @@ return 0, nil, nil, nil, fmt.Errorf("unrecognized binary format") } + +func findPESymbol(f *pe.File, name string) (*pe.Symbol, error) { + for _, s := range f.Symbols { + if s.Name != name { + continue + } + if s.SectionNumber <= 0 { + return nil, fmt.Errorf("symbol %s: invalid section number %d", name, s.SectionNumber) + } + if len(f.Sections) < int(s.SectionNumber) { + return nil, fmt.Errorf("symbol %s: section number %d is larger than max %d", name, s.SectionNumber, len(f.Sections)) + } + return s, nil + } + return nil, fmt.Errorf("no %s symbol found", name) +}
-
loadPETable
関数の新規追加: PEファイルからシンボルペア(開始と終了)によって定義されるテーブルデータを読み込むためのヘルパー関数が追加されました。--- a/src/cmd/objdump/main.go +++ b/src/cmd/objdump/main.go @@ -228,3 +260,23 @@ return data[ssym.Value:esym.Value], nil }
src/cmd/objdump/objdump_test.go
の新規追加
objdump
のPEファイル対応を検証するための新しいテストファイルが追加されました。
--- /dev/null
+++ b/src/cmd/objdump/objdump_test.go
@@ -0,0 +1,109 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "runtime"
+ "strconv"
+ "strings"
+ "testing"
+)
+
+func loadSyms(t *testing.T) map[string]string {
+ cmd := exec.Command("go", "tool", "nm", os.Args[0])
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("go tool nm %v: %v\n%s", os.Args[0], err, string(out))
+ }
+ syms := make(map[string]string)
+ scanner := bufio.NewScanner(bytes.NewReader(out))
+ for scanner.Scan() {
+ f := strings.Fields(scanner.Text())
+ if len(f) < 3 {
+ continue
+ }
+ syms[f[2]] = f[0]
+ }
+ if err := scanner.Err(); err != nil {
+ t.Fatalf("error reading symbols: %v", err)
+ }
+ return syms
+}
+
+func runObjDump(t *testing.T, exepath, startaddr string) (path, lineno string) {
+ addr, err := strconv.ParseUint(startaddr, 16, 64)
+ if err != nil {
+ t.Fatalf("invalid start address %v: %v", startaddr, err)
+ }
+ endaddr := fmt.Sprintf("%x", addr+10)
+ cmd := exec.Command(exepath, os.Args[0], "0x"+startaddr, "0x"+endaddr)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("go tool objdump %v: %v\n%s", os.Args[0], err, string(out))
+ }
+ f := strings.Split(string(out), "\n")
+ if len(f) < 1 {
+ t.Fatal("objdump output must have at least one line")
+ }
+ pathAndLineNo := f[0]
+ f = strings.Split(pathAndLineNo, ":")
+ if runtime.GOOS == "windows" {
+ switch len(f) {
+ case 2:
+ return f[0], f[1]
+ case 3:
+ return f[0] + ":" + f[1], f[2]
+ default:
+ t.Fatalf("no line number found in %q", pathAndLineNo)
+ }
+ }
+ if len(f) != 2 {
+ t.Fatalf("no line number found in %q", pathAndLineNo)
+ }
+ return f[0], f[1]
+}
+
+// This is line 75. The test depends on that.
+func TestObjDump(t *testing.T) {
+ if runtime.GOOS == "plan9" {
+ t.Skip("skipping test; see http://golang.org/issue/7947")
+ }
+ syms := loadSyms(t)
+
+ tmpDir, err := ioutil.TempDir("", "TestObjDump")
+ if err != nil {
+ t.Fatal("TempDir failed: ", err)
+ }
+ defer os.RemoveAll(tmpDir)
+
+ exepath := filepath.Join(tmpDir, "testobjdump.exe")
+ out, err := exec.Command("go", "build", "-o", exepath, "cmd/objdump").CombinedOutput()
+ if err != nil {
+ t.Fatalf("go build -o %v cmd/objdump: %v\n%s", exepath, err, string(out))
+ }
+
+ srcPath, srcLineNo := runObjDump(t, exepath, syms["cmd/objdump.TestObjDump"])
+ fi1, err := os.Stat("objdump_test.go")
+ if err != nil {
+ t.Fatalf("Stat failed: %v", err)
+ }
+ fi2, err := os.Stat(srcPath)
+ if err != nil {
+ t.Fatalf("Stat failed: %v", err)
+ }
+ if !os.SameFile(fi1, fi2) {
+ t.Fatalf("objdump_test.go and %s are not same file", srcPath)
+ }
+ if srcLineNo != "76" {
+ t.Fatalf("line number = %v; want 76", srcLineNo)
+ }
+}
コアとなるコードの解説
src/cmd/objdump/main.go
の変更点
main.go
の変更は、objdump
がPEファイルを扱う際の .gosymtab
と .gopclntab
の読み込み方法を根本的に改善しています。
-
loadTables
関数の修正: 変更前は、PEファイルの場合でも他の形式と同様にobj.Section(".gosymtab")
やobj.Section(".gopclntab")
のようにセクション名を直接指定してデータを取得しようとしていました。しかし、PEファイルではこれらのGo特有のテーブルが、必ずしも独立した名前付きセクションとして存在するとは限りません。代わりに、特定のシンボル(例:pclntab
とepclntab
)によってその開始と終了がマークされている場合があります。 修正後は、loadPETable(obj, "pclntab", "epclntab")
とloadPETable(obj, "symtab", "esymtab")
を呼び出すことで、このPEファイル特有のシンボルベースのデータ配置に対応しています。これにより、objdump
はPEファイル内のGoランタイム情報をより堅牢かつ正確に特定し、読み込むことができるようになりました。 -
findPESymbol
関数の新規追加: この関数は、PEファイル内のシンボルテーブルを走査し、指定された名前のシンボルを見つける役割を担います。Goのランタイム情報(PC-Lineテーブルやシンボルテーブル)は、PEファイル内で特定のシンボル(例:pclntab
,epclntab
,symtab
,esymtab
)によってその開始と終了がマークされている場合があるため、これらのシンボルを正確に特定することが重要です。 関数は、シンボルが見つかった場合にそのpe.Symbol
オブジェクトを返しますが、シンボルのセクション番号が有効であること(0より大きいこと)や、セクションの範囲内にあることを厳密にチェックすることで、不正なシンボル参照を防ぎ、堅牢性を高めています。 -
loadPETable
関数の新規追加: この関数は、findPESymbol
を利用して開始シンボル (sname
) と終了シンボル (ename
) を取得し、それらが同じセクション内にあることを確認します。これは、テーブルが単一の連続したメモリ領域にあることを保証するためです。 その後、該当するセクションの生データを取得し、開始シンボルの値 (ssym.Value
) から終了シンボルの値 (esym.Value
) までの範囲をスライスすることで、目的のテーブル(PC-Lineテーブルまたはシンボルテーブル)のバイトデータを抽出します。 この関数は、PEファイル特有のシンボルベースのデータ配置に対応し、正確なテーブルデータを取得するための汎用的なメカニズムを提供します。これにより、objdump
はPEファイルからGoランタイムのデバッグ情報を正しく読み取れるようになります。
src/cmd/objdump/objdump_test.go
の新規追加
このテストファイルは、objdump
がWindows PE実行ファイルを正しく処理できるようになったことを検証するために不可欠です。
-
loadSyms
関数:go tool nm
コマンドを実行して、テスト対象の実行ファイル(このテストバイナリ自身)からシンボル情報を抽出します。これにより、テスト対象の関数(例:TestObjDump
)のアドレスをプログラム的に取得できます。これは、objdump
が特定のコードアドレスに対して正しい情報を返すことを検証するために必要です。 -
runObjDump
関数: ビルドされたobjdump
実行ファイルに対して、テスト対象の実行ファイルと特定のアドレス範囲を引数として渡し、objdump
コマンドを実行します。そして、その出力からソースファイル名と行番号を解析して返します。 特に注目すべきは、runtime.GOOS == "windows"
のブロックです。Windowsのパス形式(例:C:\path\to\file.go
)は、コロン (:
) がドライブレターの区切りにも使われるため、Unix系のパスとは異なる解析ロジックが必要になります。このテスト関数は、Windows特有のパス形式にも対応できるように、出力の解析ロジックを調整しています。これにより、Windows環境でのobjdump
の出力が正しく解釈されることを保証します。 -
TestObjDump
関数: このメインのテスト関数は、以下の手順でobjdump
のPEファイル対応をエンドツーエンドで検証します。loadSyms
を呼び出して、TestObjDump
関数自身のアドレスを取得します。- 一時ディレクトリを作成し、そこに
cmd/objdump
をビルドしてtestobjdump.exe
として保存します。これにより、テスト環境で独立したobjdump
バイナリを使用できます。 runObjDump
を呼び出して、ビルドしたobjdump
を使って、テスト対象の実行ファイルとTestObjDump
関数自身のアドレスに対してobjdump
を実行します。objdump
の出力から得られたソースファイル名 (srcPath
) と行番号 (srcLineNo
) が、期待される値(このテストファイル自身のパスと、TestObjDump
関数内の特定の行番号76
)と一致するかどうかを検証します。os.SameFile
を使用して、objdump
が報告したファイルパスが、実際にテストファイル自身のパスと同じファイルを参照していることを確認します。これは、シンボル解決が正しいファイルに紐付いていることを保証するために重要です。
これらのテストは、objdump
がWindows PE実行ファイルからGoランタイムのデバッグ情報を正確に抽出し、それをソースコードの正しい位置にマッピングできることを、実際の実行レベルで保証します。
関連リンク
- Go issue tracker (具体的なissueは特定できませんでしたが、このコミットが解決した問題の背景には、ユーザーからの報告があったと推測されます)
- Go
debug/pe
パッケージのドキュメント: https://pkg.go.dev/debug/pe - Go
cmd/objdump
のソースコード (変更後のコード): https://github.com/golang/go/tree/master/src/cmd/objdump
参考にした情報源リンク
- Go言語の公式ドキュメント: Goのツールチェイン、バイナリ構造、ランタイムに関する一般的な情報。
- Go言語のソースコード: 特に
src/debug/pe
パッケージとsrc/cmd/objdump
の実装。 - PEファイル形式に関する一般的な情報源: MicrosoftのPE/COFF仕様など、PEファイルの構造とセクションに関する詳細な情報。
- Goのissueトラッカーとコードレビューシステム: 過去の関連する議論や変更の経緯を理解するための情報源。