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
360
0
Share
詳解!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
monorepo の Go テストをはやくした〜い!~最小の依存解決への道のり~ / faster-testing-of-monorepos
convto
2
640
MCPと認可まわりの話 / mcp_and_authorization
convto
2
1.4k
バクラクの認証基盤の成長と現在地 / bakuraku-authn-platform
convto
4
2k
gob バイナリが Go バージョンによって 出力が変わることについて調べてみた / Investigating How gob Binary Output Changes Across Go Versions
convto
0
160
Go 関連の個人的おもしろCVE 5選 / my favorite go cve
convto
3
560
バイナリを眺めてわかる gob encoding の仕様と性質、適切な使い方 / understanding gob encoding
convto
6
3.3k
みんなでたのしむ math/big / i love math big
convto
0
330
Go1.22からの疑似乱数生成器について/go-122-pseudo-random-generator
convto
2
1k
Go1.20からサポートされるtree構造のerrの紹介と、treeを考慮した複数マッチができるライブラリを作った話/introduction of tree structure err added since go 1_20
convto
0
1.4k
Other Decks in Programming
See All in Programming
レガシーPHP転生 〜父がドメインエキスパートだったのでDDD+Claude Codeでチート開発します〜
panda_program
0
680
VueエンジニアがReactを触って感じた_設計の違い
koukimiura
0
170
Coding as Prompting Since 2025
ragingwind
0
790
夢の無限スパゲッティ製造機 -実装篇- #phpstudy
o0h
PRO
0
200
LM Linkで(非力な!)ノートPCでローカルLLM
seosoft
0
460
forteeの改修から振り返るPHPerKaigi 2026
muno92
PRO
3
270
3分でわかるatama plusのQA/about atama plus QA
atamaplus
0
140
事業会社でのセキュリティ長期インターンについて
masachikaura
0
240
ファインチューニングせずメインコンペを解く方法
pokutuna
0
300
Mastering Event Sourcing: Your Parents Holidayed in Yugoslavia
super_marek
0
150
「効かない!」依存性注入(DI)を活用したAPI Platformのエラーハンドリング奮闘記
mkmk884
0
320
Java 21/25 Virtual Threads 소개
debop
0
340
Featured
See All Featured
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
54k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
370
Believing is Seeing
oripsolob
1
110
Fireside Chat
paigeccino
42
3.9k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
420
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.6k
WENDY [Excerpt]
tessaabrams
9
37k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
260
Designing Experiences People Love
moore
143
24k
KATA
mclloyd
PRO
35
15k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.3k
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 で実 装されてるので、気になる実装があったら確認してみるとおもしろいかもしれませ ん!
ご清聴ありがとうございました