Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ログから学ぶgo build
Search
nasa
September 28, 2023
Technology
1.6k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ログから学ぶgo build
https://golangtokyo.connpass.com/event/293636/
nasa
September 28, 2023
More Decks by nasa
See All by nasa
難解な自己紹介プログラムを書く
nasa_desu
1
410
鉄は熱いうちに打て - Kaigi Effect LT大会
nasa_desu
2
610
リンカを変えてgo buildを 速く出来るか
nasa_desu
2
4k
RustでOS開発はじめの一歩
nasa_desu
8
7.6k
goのメモリアロケーターの話
nasa_desu
1
840
GoとRust - 並行処理編
nasa_desu
5
4.2k
Other Decks in Technology
See All in Technology
振り返りこそエンジニアの本領
negima
0
140
AI-DLCって実際どう? 〜聞きたいこと全部聞いてみる〜
news_it_enj
0
150
研究開発部の紹介 / Sansan R&D Profile
sansan33
PRO
4
25k
KPIだけでは評価できないプロダクトが考えるべき Evalsという第二の評価系 / Beyond KPIs: Evals as a Second Evaluation Framework for Products #PdEConf
aki_iinuma
1
2.2k
Bet AI Day 2026丨バクラク Autopilot、業務システムの再設計
layerx
PRO
1
850
Oracle AI Databaseデータベース・サービス: BaseDB/ExaDB-Dの可用性
oracle4engineer
PRO
1
1.1k
PdMをやめて、 "プロダクトビルダー"という 働き方に変えました / PdM to Product Builder
shikichee
2
640
みてねにおけるAI-DLC導入活動とAIドリブン開発の現在地/JAWS-UG AI-DLC #2
isaoshimizu
2
330
GuardDuty 検知対応を DevOps Agent で効率化しようとしている話 / GuardDuty Investigations with DevOps Agent
masahirokawahara
1
150
Point Cloud as a Foreign Language for Multi-modal Large Language Model
takmin
0
360
Bet AI Day 2026丨AIを「使う」から、AIが「働く」へ ― LayerXが進める「組織AI」の社会実装
layerx
PRO
2
1.5k
[RSJ26] NarrativeFlow: Flow-Based Vision-Language-Action Model Using Robot Velocity Fields
keio_smilab
PRO
0
140
Featured
See All Featured
BBQ
matthewcrist
89
10k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.2k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
680
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
The Pragmatic Product Professional
lauravandoore
37
7.4k
Marketing to machines
jonoalderson
1
5.7k
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
260
Music & Morning Musume
bryan
47
7.4k
Transcript
© 2023 Wantedly, Inc. ログから学ぶgo build golang.tokyo #33 Sep. 29
2023 - nasa
今日のテーマ © 2023 Wantedly, Inc.
テーマ go buildのログを元に ソースコードが実行ファイルにな るまでを理解する © 2023 Wantedly, Inc.
準備 © 2023 Wantedly, Inc.
準備 package main import "fmt" func main() { fmt.Println("Hello World")
} © 2023 Wantedly, Inc. 利用するコード (main.go)
準備 go buildコマンド © 2023 Wantedly, Inc. go build -x
-p 1 -work main.go
準備 go buildコマンド © 2023 Wantedly, Inc. go build -x
-p 1 -work main.go -xオプションによりgo buildに呼び出されるコマンドを表示
go buildコマンド © 2023 Wantedly, Inc. go build -x -p
1 -work main.go -pオプションは並列数 ログの読み取りやすさのために1並列で実行 準備
go buildコマンド © 2023 Wantedly, Inc. go build -x -p
1 -work main.go -workは作業ディレクトリを残すオプション ビルド中に吐かれる中間生成物を残しといて調査に使う 準備
では実行してみよう © 2023 Wantedly, Inc.
© 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
© 2023 Wantedly, Inc. なんかいっぱい出た
© 2023 Wantedly, Inc. 発表を聞き終わった後にはこれが理解できる(はず)
全体像 © 2023 Wantedly, Inc.
© 2023 Wantedly, Inc. 複数のビルドステップ 全体像 mkdirを境として複数のビルドステップが存在 今回の例だとb001~b041
全体像 © 2023 Wantedly, Inc. 簡略化した全体像 各ステップの出力ファイルの依存関係を表した図 例えば、b040の出力がb031で使用される パッケージの依存関係に基づいてコンパイル 最後のb001/execで実行ファイルが生成
全体像 © 2023 Wantedly, Inc. 下記のように名付けて話を進めます b001~b041全体をコンパイルプロセス b001/execをリンクプロセス
全体像 © 2023 Wantedly, Inc. コンパイルプロセスでは利用するパッケージ毎に コンパイルする ソースコードが機械語へ リンクプロセスでは機械語をつなぎ合わせて実 行ファイルにする
全体像 © 2023 Wantedly, Inc. 依存関係を考慮しないと下記
全体像 © 2023 Wantedly, Inc. (余談) 簡略化しないとこうなる
コンパイルプロセス © 2023 Wantedly, Inc.
© 2023 Wantedly, Inc. パッケージ毎にソースコードを機械語に変換する コンパイルプロセス
コンパイルプロセス 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
コンパイルプロセス © 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ファイルに情報をまとめている
© 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構築・型チェックに利用 コンパイルプロセス
© 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で個々のファイルを見ることが出来る コンパイルプロセス
© 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で人が読める形式に コンパイルプロセス
© 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 コンパイルプロセス
(余裕があれば) 低レベルなパッケージの コンパイル © 2023 Wantedly, Inc.
© 2023 Wantedly, Inc. 標準パッケージを見てみると一部関数はアセンブリ言語で実装し てある こういった低レベルなパッケージは先程とはプロセスが異なる コンパイルプロセス
コンパイルプロセス 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
コンパイルプロセス © 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
コンパイルプロセス © 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を利用
コンパイルプロセス © 2023 Wantedly, Inc. 1. compile /usr/local/go/pkg/tool/darwin_arm64/pack r $WORK/b028/_pkg_.a
$WORK/b028/asm.o # internal 最後に生成物をまとめる
リンクプロセス © 2023 Wantedly, Inc.
リンク © 2023 Wantedly, Inc. リンクって何? コンパイルプロセスで作ったオブジェクトファイル(.oファイル)をつなぎ合わせて実行ファイルを作 る
リンク © 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にまとまっている
リンク © 2023 Wantedly, Inc. アドレス情報を埋める オブジェクトファイルと実行ファイルの差分を見てみる `R_CALL`が消え、0(PC)と適当な値だったがアドレス(ラベル)になっている
リンク © 2023 Wantedly, Inc. 実行ファイル macOSやLinuxなどターゲットに応じた実行形式をサポートしている macOSだったらMach-O linuxならELF $
file main main: Mach-O 64-bit executable arm64
ということで 実行ファイルが手に入った🎉 © 2023 Wantedly, Inc.
まとめ © 2023 Wantedly, Inc.
まとめ © 2023 Wantedly, Inc. • ログや生成ファイルをガチャガチャやるだけでも色々と分かる • 豊富なデバッグオプション・デバッグツールが揃ってる
まとめ © 2023 Wantedly, Inc. 扱ったのはほんの一部
俺達の戦いはこれから? © 2023 Wantedly, Inc.
自己紹介 © 2023 Wantedly, Inc. • nasa (Asan Kondo) •
Wantedly,Inc.所属 • 推薦基盤の開発・運用 • ハンドルネームnasaが欲しい ◦ GitHub: @k-nasa ◦ X(Twitter): @nasa_desu
ご清聴ありがとうございました © 2023 Wantedly, Inc.