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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
convto
September 01, 2025
Programming
0
340
詳解!defer panic recover のしくみ / Understanding defer, panic, and recover
golang\.tokyo #40 にて発表した内容です
https://golangtokyo.connpass.com/event/365231/
convto
September 01, 2025
Tweet
Share
More Decks by convto
See All by convto
monorepo の Go テストをはやくした〜い!~最小の依存解決への道のり~ / faster-testing-of-monorepos
convto
2
620
MCPと認可まわりの話 / mcp_and_authorization
convto
2
1.2k
バクラクの認証基盤の成長と現在地 / bakuraku-authn-platform
convto
4
1.7k
gob バイナリが Go バージョンによって 出力が変わることについて調べてみた / Investigating How gob Binary Output Changes Across Go Versions
convto
0
150
Go 関連の個人的おもしろCVE 5選 / my favorite go cve
convto
3
530
バイナリを眺めてわかる gob encoding の仕様と性質、適切な使い方 / understanding gob encoding
convto
6
3.1k
みんなでたのしむ math/big / i love math big
convto
0
310
Go1.22からの疑似乱数生成器について/go-122-pseudo-random-generator
convto
2
950
Go1.20からサポートされるtree構造のerrの紹介と、treeを考慮した複数マッチができるライブラリを作った話/introduction of tree structure err added since go 1_20
convto
0
1.3k
Other Decks in Programming
See All in Programming
例外処理とどう使い分ける?Result型を使ったエラー設計 #burikaigi
kajitack
16
5.8k
Kotlin Multiplatform Meetup - Compose Multiplatform 외부 의존성 아키텍처 설계부터 운영까지
wisemuji
0
180
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
220
GISエンジニアから見たLINKSデータ
nokonoko1203
0
190
AIエージェント、”どう作るか”で差は出るか? / AI Agents: Does the "How" Make a Difference?
rkaga
4
1.9k
公共交通オープンデータ × モバイルUX 複雑な運行情報を 『直感』に変換する技術
tinykitten
PRO
0
200
AI前提で考えるiOSアプリのモダナイズ設計
yuukiw00w
0
220
余白を設計しフロントエンド開発を 加速させる
tsukuha
7
2k
Honoを使ったリモートMCPサーバでAIツールとの連携を加速させる!
tosuri13
1
170
コマンドとリード間の連携に対する脅威分析フレームワーク
pandayumi
1
420
Architectural Extensions
denyspoltorak
0
240
.NET Conf 2025 の興味のあるセッ ションを復習した / dotnet conf 2025 quick recap for backend engineer
tomohisa
0
120
Featured
See All Featured
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
50
How to train your dragon (web standard)
notwaldorf
97
6.5k
Writing Fast Ruby
sferik
630
62k
Docker and Python
trallard
47
3.7k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
61
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Chasing Engaging Ingredients in Design
codingconduct
0
100
Build The Right Thing And Hit Your Dates
maggiecrowley
38
3k
The Power of CSS Pseudo Elements
geoffreycrofte
80
6.1k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
84
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
130
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
0
120
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 で実 装されてるので、気になる実装があったら確認してみるとおもしろいかもしれませ ん!
ご清聴ありがとうございました