Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
© 2023 Wantedly, Inc. ログから学ぶgo build golang.tokyo #33 Sep. 29 2023 - nasa
Slide 2
Slide 2 text
今日のテーマ © 2023 Wantedly, Inc.
Slide 3
Slide 3 text
テーマ go buildのログを元に ソースコードが実行ファイルにな るまでを理解する © 2023 Wantedly, Inc.
Slide 4
Slide 4 text
準備 © 2023 Wantedly, Inc.
Slide 5
Slide 5 text
準備 package main import "fmt" func main() { fmt.Println("Hello World") } © 2023 Wantedly, Inc. 利用するコード (main.go)
Slide 6
Slide 6 text
準備 go buildコマンド © 2023 Wantedly, Inc. go build -x -p 1 -work main.go
Slide 7
Slide 7 text
準備 go buildコマンド © 2023 Wantedly, Inc. go build -x -p 1 -work main.go -xオプションによりgo buildに呼び出されるコマンドを表示
Slide 8
Slide 8 text
go buildコマンド © 2023 Wantedly, Inc. go build -x -p 1 -work main.go -pオプションは並列数 ログの読み取りやすさのために1並列で実行 準備
Slide 9
Slide 9 text
go buildコマンド © 2023 Wantedly, Inc. go build -x -p 1 -work main.go -workは作業ディレクトリを残すオプション ビルド中に吐かれる中間生成物を残しといて調査に使う 準備
Slide 10
Slide 10 text
では実行してみよう © 2023 Wantedly, Inc.
Slide 11
Slide 11 text
© 2023 Wantedly, Inc. $ go build -x -p 1 -work main.go WORK=/var/folders/xx/xxxxxxxxxxxxx/T/go-buildxxxxxxxx mkdir -p $WORK/b005/ cat >/var/folders/xx/xxxxxxxxxxxxx/T/go-buildxxxxxxxx/b005/importcfg << 'EOF' # internal # import config EOF cd /Users/xxxxx/lab/sandbox/playground_go /usr/local/go/pkg/tool/xxxxxxxx/compile -o $WORK/b005/_pkg_.a -trimpath "$WORK/b005=>" -p internal/goarch -std -+ -complete -buildid M8znE3RFNIIsfAk_eE8O/M8znE3RFNIIsfAk_eE8O -goversion go1.20.1 -c=8 -nolocalimports -importcfg $WORK/b005/importcfg -pack /usr/local/go/src/internal/goarch/goarch.go /usr/local/go/src/internal/goarch/goarch_amd64.go /usr/local/go/src/internal/goarch/zgoarch_amd64.go /usr/local/go/pkg/tool/xxxxxxxx/buildid -w $WORK/b005/_pkg_.a # internal cp $WORK/b005/_pkg_.a /Users/xxxxx/Library/Caches/go-build/8c/8cf7915e43e6ec3a1ceac20e15009d87c0d26d4aa40409e5dc8b2e935d6d1014-d # internal mkdir -p $WORK/b006/ cat >/var/folders/xx/xxxxxxxxxxxxx/T/go-buildxxxxxxxx/b006/importcfg << 'EOF' # internal # import config EOF /usr/local/go/pkg/tool/xxxxxxxx/compile -o $WORK/b006/_pkg_.a -trimpath "$WORK/b006=>" -p internal/unsafeheader -std -complete -buildid sD4mccwa9DUJsmqBZGxG/sD4mccwa9DUJsmqBZGxG -goversion go1.20.1 -c=8 -nolocalimports -importcfg $WORK/b006/importcfg -pack /usr/local/go/src/internal/unsafeheader/unsafeheader.go /usr/local/go/pkg/tool/xxxxxxxx/buildid -w $WORK/b006/_pkg_.a # internal
Slide 12
Slide 12 text
© 2023 Wantedly, Inc. なんかいっぱい出た
Slide 13
Slide 13 text
© 2023 Wantedly, Inc. 発表を聞き終わった後にはこれが理解できる(はず)
Slide 14
Slide 14 text
全体像 © 2023 Wantedly, Inc.
Slide 15
Slide 15 text
© 2023 Wantedly, Inc. 複数のビルドステップ 全体像 mkdirを境として複数のビルドステップが存在 今回の例だとb001~b041
Slide 16
Slide 16 text
全体像 © 2023 Wantedly, Inc. 簡略化した全体像 各ステップの出力ファイルの依存関係を表した図 例えば、b040の出力がb031で使用される パッケージの依存関係に基づいてコンパイル 最後のb001/execで実行ファイルが生成
Slide 17
Slide 17 text
全体像 © 2023 Wantedly, Inc. 下記のように名付けて話を進めます b001~b041全体をコンパイルプロセス b001/execをリンクプロセス
Slide 18
Slide 18 text
全体像 © 2023 Wantedly, Inc. コンパイルプロセスでは利用するパッケージ毎に コンパイルする ソースコードが機械語へ リンクプロセスでは機械語をつなぎ合わせて実 行ファイルにする
Slide 19
Slide 19 text
全体像 © 2023 Wantedly, Inc. 依存関係を考慮しないと下記
Slide 20
Slide 20 text
全体像 © 2023 Wantedly, Inc. (余談) 簡略化しないとこうなる
Slide 21
Slide 21 text
コンパイルプロセス © 2023 Wantedly, Inc.
Slide 22
Slide 22 text
© 2023 Wantedly, Inc. パッケージ毎にソースコードを機械語に変換する コンパイルプロセス
Slide 23
Slide 23 text
コンパイルプロセス 1. importcfgの作成 2. compile 3. ビルドキャッシュの作成 © 2023 Wantedly, Inc. mkdir -p $WORK/b002/ # 1. importcfg cat >/var/folders/gb/0bh7j48d59n5fsy0wvpjd2fm0000gn/T/go-build3269867993/b002/importcfg << 'EOF' # internal # import config EOF # 2. compile /usr/local/go/pkg/tool/darwin_arm64/compile -o $WORK/b002/_pkg_.a -importcfg $WORK/b002/importcfg /usr/local/go/src/fmt/scan.go # 3. build cache /usr/local/go/pkg/tool/darwin_arm64/buildid -w $WORK/b002/_pkg_.a # internal cp $WORK/b002/_pkg_.a /Users/Library/Caches/go-build/b6/b68267d8212b1d8b8e54044a24b10869a453ec4e4a25163833c4f5928bd66aa6-d # internal
Slide 24
Slide 24 text
コンパイルプロセス © 2023 Wantedly, Inc. 1. importcfg cat >/var/folders/gb/0bh7j48d59n5fsy0wvpjd2fm0000gn/T/go-build717416899/b033/importcfg << 'EOF' # internal # import config packagefile errors=/var/folders/gb/0bh7j48d59n5fsy0wvpjd2fm0000gn/T/go-build717416899/b003/_pkg_.a packagefile internal/syscall/unix=/var/folders/gb/0bh7j48d59n5fsy0wvpjd2fm0000gn/T/go-build717416899/b034/_pkg_.a (略) EOF コンパイル時に依存しているパッケージの情報が必要になる importcfgファイルに情報をまとめている
Slide 25
Slide 25 text
© 2023 Wantedly, Inc. 2. compile $ /usr/local/go/pkg/tool/darwin_arm64/compile \ -o $WORK/b005/_pkg_.a \ -importcfg $WORK/b005/importcfg \ /usr/local/go/src/internal/goarch/goarch.go -o 出力ファイル -importcfg 先程作ったimportcfgはここで使う。AST構築・型チェックに利用 コンパイルプロセス
Slide 26
Slide 26 text
© 2023 Wantedly, Inc. 2. compile $ go tool pack t $WORK/b002/_pkg_.a # 中身の確認 __.PKGDEF _go_.o $ go tool pack x $WORK/b002/_pkg_.a # 取り出す はたして何が作成されたのか? .aはアーカイブファイル(複数のファイルをまとめて一つのファイルへ変換したファイル) go tool packで個々のファイルを見ることが出来る コンパイルプロセス
Slide 27
Slide 27 text
© 2023 Wantedly, Inc. 2. compile $ go tool objdump _go_.o … SUB $80, RSP, R17 CMP R16, R17 BLS 256(PC) __.PKGDEF パッケージ情報が詰まったファイル _go.o オブジェクトファイル プログラムの断片で機械語が書いてある go tool objdumpで人が読める形式に コンパイルプロセス
Slide 28
Slide 28 text
© 2023 Wantedly, Inc. 3. ビルドキャッシュ 各ステップごとにキャッシュを作成 ソースコードが変わってなければキャッシュを再利用 mkdir -p $WORK/b005/ (略) /usr/local/go/pkg/tool/xxxxxxxx/buildid -w $WORK/b005/_pkg_.a # internal cp $WORK/b005/_pkg_.a /Users/xxxxx/Library/Caches/go-build/8c/8cf7915e43e6ec3a1ceac20e15009d87c0d26d4aa40409e5dc8b2e935d6d10 14-d # internal コンパイルプロセス
Slide 29
Slide 29 text
(余裕があれば) 低レベルなパッケージの コンパイル © 2023 Wantedly, Inc.
Slide 30
Slide 30 text
© 2023 Wantedly, Inc. 標準パッケージを見てみると一部関数はアセンブリ言語で実装し てある こういった低レベルなパッケージは先程とはプロセスが異なる コンパイルプロセス
Slide 31
Slide 31 text
コンパイルプロセス 1. symabi 2. compile © 2023 Wantedly, Inc. /usr/local/go/pkg/tool/darwin_arm64/asm -p sync/atomic -gensymabis -o $WORK/b028/symabis ./asm.s /usr/local/go/pkg/tool/darwin_arm64/compile \ -o $WORK/b028/_pkg_.a \ -symabis $WORK/b028/symabis \ -importcfg $WORK/b028/importcfg \ -asmhdr $WORK/b028/go_asm.h \ /usr/local/go/src/sync/atomic/value.go /usr/local/go/pkg/tool/darwin_arm64/asm -p sync/atomic -o $WORK/b028/asm.o ./asm.s /usr/local/go/pkg/tool/darwin_arm64/pack r $WORK/b028/_pkg_.a $WORK/b028/asm.o # internal
Slide 32
Slide 32 text
コンパイルプロセス © 2023 Wantedly, Inc. 1. symabis usr/local/go/pkg/tool/darwin_arm64/asm -p sync/atomic -gensymabis -o $WORK/b028/symabis ./asm.s アセンブリのABIをファイルに書き出す ABIは呼出規約を定めたもの 引数のこの順番でスタック・レジスタに置きますね 返り値はこの順番でスタック・レジスタに置きますね ABIドキュメント: https://github.com/golang/go/blob/master/src/cmd/compile/abi-internal.md ソースコード: src/cmd/internal/obj/link.go
Slide 33
Slide 33 text
コンパイルプロセス © 2023 Wantedly, Inc. 1. compile /usr/local/go/pkg/tool/darwin_arm64/compile -o $WORK/b028/_pkg_.a -p sync/atomic -symabis $WORK/b028/symabis -importcfg $WORK/b028/importcfg -pack -asmhdr $WORK/b028/go_asm.h \ /usr/local/go/src/sync/atomic/doc.go \ /usr/local/go/src/sync/atomic/type.go \ /usr/local/go/src/sync/atomic/value.go /usr/local/go/pkg/tool/darwin_arm64/asm -p sync/atomic -o $WORK/b028/asm.o ./asm.s ソースコードとアセンブリ言語を機械語に変換 さっき生成したsymabisを利用
Slide 34
Slide 34 text
コンパイルプロセス © 2023 Wantedly, Inc. 1. compile /usr/local/go/pkg/tool/darwin_arm64/pack r $WORK/b028/_pkg_.a $WORK/b028/asm.o # internal 最後に生成物をまとめる
Slide 35
Slide 35 text
リンクプロセス © 2023 Wantedly, Inc.
Slide 36
Slide 36 text
リンク © 2023 Wantedly, Inc. リンクって何? コンパイルプロセスで作ったオブジェクトファイル(.oファイル)をつなぎ合わせて実行ファイルを作 る
Slide 37
Slide 37 text
リンク © 2023 Wantedly, Inc. アドレス情報を埋める オブジェクトファイルでは関数のアドレスを仮置きしている `R_CALLARM64`のように仮置きの場所がマーキングしてある $ go tool objdump b001/_pkg_.a TEXT main.main(SB) gofile../main.go print.go:314 0x13cc 94000000 CALL 0(PC) [0:4]R_CALLARM64:fmt.Fprintln 余談: リロケーションタイプはsrc/cmd/internal/objabi/reloctype.goにまとまっている
Slide 38
Slide 38 text
リンク © 2023 Wantedly, Inc. アドレス情報を埋める オブジェクトファイルと実行ファイルの差分を見てみる `R_CALL`が消え、0(PC)と適当な値だったがアドレス(ラベル)になっている
Slide 39
Slide 39 text
リンク © 2023 Wantedly, Inc. 実行ファイル macOSやLinuxなどターゲットに応じた実行形式をサポートしている macOSだったらMach-O linuxならELF $ file main main: Mach-O 64-bit executable arm64
Slide 40
Slide 40 text
ということで 実行ファイルが手に入った🎉 © 2023 Wantedly, Inc.
Slide 41
Slide 41 text
まとめ © 2023 Wantedly, Inc.
Slide 42
Slide 42 text
まとめ © 2023 Wantedly, Inc. ● ログや生成ファイルをガチャガチャやるだけでも色々と分かる ● 豊富なデバッグオプション・デバッグツールが揃ってる
Slide 43
Slide 43 text
まとめ © 2023 Wantedly, Inc. 扱ったのはほんの一部
Slide 44
Slide 44 text
俺達の戦いはこれから? © 2023 Wantedly, Inc.
Slide 45
Slide 45 text
自己紹介 © 2023 Wantedly, Inc. ● nasa (Asan Kondo) ● Wantedly,Inc.所属 ● 推薦基盤の開発・運用 ● ハンドルネームnasaが欲しい ○ GitHub: @k-nasa ○ X(Twitter): @nasa_desu
Slide 46
Slide 46 text
ご清聴ありがとうございました © 2023 Wantedly, Inc.