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
詳解!defer panic recover のしくみ / Understanding def...
Search
convto
September 01, 2025
Programming
390
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
詳解!defer panic recover のしくみ / Understanding defer, panic, and recover
golang\.tokyo #40 にて発表した内容です
https://golangtokyo.connpass.com/event/365231/
convto
September 01, 2025
More Decks by convto
See All by convto
Go 1.27 の標準パッケージに uuid が入った!のでいろいろ喋る / go_127_std_go_uuid
convto
3
560
monorepo の Go テストをはやくした〜い!~最小の依存解決への道のり~ / faster-testing-of-monorepos
convto
2
680
MCPと認可まわりの話 / mcp_and_authorization
convto
2
1.6k
バクラクの認証基盤の成長と現在地 / bakuraku-authn-platform
convto
4
2.3k
gob バイナリが Go バージョンによって 出力が変わることについて調べてみた / Investigating How gob Binary Output Changes Across Go Versions
convto
0
180
Go 関連の個人的おもしろCVE 5選 / my favorite go cve
convto
3
610
バイナリを眺めてわかる gob encoding の仕様と性質、適切な使い方 / understanding gob encoding
convto
6
3.5k
みんなでたのしむ math/big / i love math big
convto
0
360
Go1.22からの疑似乱数生成器について/go-122-pseudo-random-generator
convto
2
1.1k
Other Decks in Programming
See All in Programming
How I Won Prize Money at a Hackathon Using Codex and Symphony Alpha
yasei_no_otoko
0
120
レビュー履歴をAIに食わせて、 Compose移行を加速するs
shihochan
0
160
全PRの83%がAIレビューだけでマージできるようになった開発組織はその後どうなったか
athug
1
1.9k
「つくるAI」だけではバグは見つからない ~テストに必要な「見つけるAI」を分離させる戦略~
mfunaki
0
120
ここ半年くらいでAIに作らせたR用ツール
eitsupi
0
390
Laravel Boostに学ぶ、AIにPHPを書かせる技術 〜OSSの実装から蒸留するエージェント制御の王道〜
kentaroutakeda
3
750
jsmini JavaScript Engine を作ってみた話
yosuke_furukawa
PRO
0
350
MySQLとPostgreSQLって何が違うの?
akagami
0
120
Oxlintはいいぞ(続)
yug1224
1
290
Hono + Inertia + React で LP を構築した話
oukayuka
2
110
What's New in Android 2026
veronikapj
0
270
「寝てても仕事が進む」Claude Codeで組む第二の脳
tomoyafujita2016
0
350
Featured
See All Featured
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.4k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
GraphQLとの向き合い方2022年版
quramy
50
15k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.4k
The Curse of the Amulet
leimatthew05
2
14k
Into the Great Unknown - MozCon
thekraken
41
2.7k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2.1k
The Art of Programming - Codeland 2020
erikaheidi
57
14k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.2k
Transcript
詳解!defer / panic / recover のしくみ 2025/09/01(月) golang.tokyo #40
自己紹介 @convto 株式会社LayerX所属 たまにGoのランタイムを読んだりしてい ます (読みはこんぶとです)
defer 便利ですよね
defer は便利 - 安全にリソース解放ができたり - 安全に recover できたり - 「最後に実行される」という性質は便利
defer について知っていること - その関数の最後に実行される - 複数あると LIFO で実行される
ぼくは defer のことをなにも知らない
ということで調べる - どこから調べよう - 組み込み予約語なので実装自体は runtime にありそう - どの runtime
関数や構造によって管理されているかはわからない
ということで調べる - どこから調べよう - 組み込み予約語なので実装自体は runtime にありそう - どの runtime
関数や構造によって管理されているかはわからない
どの関数がとっかかりになるか探そう - こういうときは、最小コードを書いて go tool compile からの go tool objdump
が 便利 - 最小コードはさっきの→で - 以降 go 1.25.0 でやっていきます o tool compile main.go
go tool compile & objdump 結果
go tool compile & objdump 結果
runtime.deferreturn をみる - panic .go に処理が書いてある - _panic という構造にマークをつけてる -
pc, sp を登録 - nextDefer を呼ぶ
なるほどわからん
がとっかかりは得られた
とっかかり - コメントにあるとおり deferreturn は caller 側の最後に defer 評価を差し込むような 挙動を示しそう
- これはさっき貼った objdump の結果とも一致する - おそらく nextDefer で LIFO の defer スタックを消化していきそう - 消化する場所はここっぽいんだけど、積んでるのはどこ? - _panic 構造 に色々処理が生えてそう
defer スタックどこで積んでるの
defer スタックを積むのはどこ? - さっきの objdump したとき、なんか関数積まれてた - そいつがおそらく defer に登録した関数なので、関数名とかを書いてもう一回見て
みる
defer スタックを積むのはどこ?
objdump
objdump
objdump - なんか積まれてそう - deferreturn が開始点で、スタック で defer func を呼び出す感じっぽ
い - deferreturn は defer の開始点を 初期化し、さらにここに積んだ defer を nextDefer で全て消化して そう
defer スタックどこで消化してるの
スタック消化 - go1.14くらいで Open-Coded defer という最適化が入ったっぽい - https://github.com/golang/proposal/blob/master/design/34481-opencoded -defers.md -
これはめちゃざっくりいうと、コンパイラ側で defer チェーンをいい感じに評価して、 そのままコンパイル結果で展開してしまうというアプローチ - 関数内の defer の数が 8 個以下だとこの最適化通るらしい - ので今回の例はこのパスを通って、コンパイラ側で展開されているはず
nextDefer - こいつがスタックに積まれた defer を消化していそう - deferreturn マーク有無でチェッ ク分岐がある -
recover マークがついてれば mcall でそこに飛んじゃう(制御 戻ってこない!) - recover はマークするだけな気配
nextDefer - さっき話してた Open-Coded 最適化を 考慮した箇所もある
nextDefer - その後 deferconvert と popDefer が呼び出される - みるものが残ってる時は true
を返して呼び出し元の探索を 継続
defer の仕組みは概ねわかった
次は panic / recover
とっかかりをみる - さっきとおなじく objdump - recover は defer の実装から、recovered フラグを立てていそう
最小コード
objdump
objdump
みると良さそうなところがわかった - gorecover と gopanic をみるといい感じそう - よしみていくぞ
recover
nextDefer - defer 評価時に recovered だっ たらそこに飛ぶだけだったことを 思い出そう - ということは
recovered ってフラ グ立てるだけなんでは?
gorecover - やっぱりそうでした - 条件満たしたら recovered にす るだけ
panic
gopanic - ざっくりいうと print して fatalpanic を呼び出している - 面白いところで言うと、読み間違ってなければ多分その時点までの defer
スタック を評価したりしてる - panic しても defer は実行される!(落ち着いて考えると、そうじゃないと recover できない)
まとめ
ざっくり関係 関数 deferreturn ←コンパイラによって関数末尾に挿入、実行時 スタックから関数を評価 (recovered だと panic からも復帰できる) defer
に登録され た関数 gorecover ↑ panic起きてるときに recovered 立てる gopanic ← fatalpanic 投げる
いい感じにわかってきた - 今回は出力からボトムアップでみていったが、結構コンパイラが仕事してそう - 評価は deferreturn を起点に実行時にやられそう - Open-Coded 最適化パスを通ったときは既に展開されてて、順序通り評価するだけ?
- 「panic 時も defer は評価する」が守られてるから recover もできる - つぎはコンパイラ側の仕事もみてみたい
そもそも defer 周りの仕組みがわかって なにがうれしいの?
しくみがわかってうれしい
というのは冗談で - 仕組みがわかると評価順についてちょっと自信が持てたりする - 自前で似たようなことやりたくなったとき、参考にできる - こういう引き出しを増やすのは楽しいし、さらにいつか役に立つかもしれない!お 得! - とくに
go は runtime におもしろ実装が多く、かつ(深入りしすぎなければ) go で実 装されてるので、気になる実装があったら確認してみるとおもしろいかもしれませ ん!
ご清聴ありがとうございました