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
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
610
MCPと認可まわりの話 / mcp_and_authorization
convto
2
1.1k
バクラクの認証基盤の成長と現在地 / 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
940
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
リリース時」テストから「デイリー実行」へ!開発マネージャが取り組んだ、レガシー自動テストのモダン化戦略
goataka
0
150
Grafana:建立系統全知視角的捷徑
blueswen
0
260
HTTPプロトコル正しく理解していますか? 〜かわいい猫と共に学ぼう。ฅ^•ω•^ฅ ニャ〜
hekuchan
2
580
PC-6001でPSG曲を鳴らすまでを全部NetBSD上の Makefile に押し込んでみた / osc2025hiroshima
tsutsui
0
200
Rubyで鍛える仕組み化プロヂュース力
muryoimpl
0
250
脳の「省エネモード」をデバッグする ~System 1(直感)と System 2(論理)の切り替え~
panda728
PRO
0
130
PostgreSQLで手軽にDuckDBを使う!DuckDB&pg_duckdb入門/osc25hi-duckdb
takahashiikki
0
230
Canon EOS R50 V と R5 Mark II 購入でみえてきた最近のデジイチ VR180 事情、そして VR180 静止画に活路を見出すまで
karad
0
140
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
540
Jetpack XR SDKから紐解くAndroid XR開発と技術選定のヒント / about-androidxr-and-jetpack-xr-sdk
drumath2237
1
220
AI Agent Tool のためのバックエンドアーキテクチャを考える #encraft
izumin5210
5
1.5k
実はマルチモーダルだった。ブラウザの組み込みAI🧠でWebの未来を感じてみよう #jsfes #gemini
n0bisuke2
3
1.4k
Featured
See All Featured
New Earth Scene 8
popppiees
0
1.3k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
200
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.6k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
26
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
10
770
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.6k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
0
170
Marketing to machines
jonoalderson
1
4.5k
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
0
81
The Curse of the Amulet
leimatthew05
0
6.5k
Leo the Paperboy
mayatellez
0
1.3k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
280
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 で実 装されてるので、気になる実装があったら確認してみるとおもしろいかもしれませ ん!
ご清聴ありがとうございました