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
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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.3k
バクラクの認証基盤の成長と現在地 / bakuraku-authn-platform
convto
4
1.9k
gob バイナリが Go バージョンによって 出力が変わることについて調べてみた / Investigating How gob Binary Output Changes Across Go Versions
convto
0
160
Go 関連の個人的おもしろCVE 5選 / my favorite go cve
convto
3
550
バイナリを眺めてわかる 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
Java 21/25 Virtual Threads 소개
debop
0
330
PHP 7.4でもOpenTelemetryゼロコード計装がしたい! / PHPerKaigi 2026
arthur1
1
520
iOS機能開発のAI環境と起きた変化
ryunakayama
0
160
LM Linkで(非力な!)ノートPCでローカルLLM
seosoft
0
400
Swift Concurrency Type System
inamiy
0
120
Feature Toggle は捨てやすく使おう
gennei
0
430
今こそ押さえておきたい アマゾンウェブサービス(AWS)の データベースの基礎 おもクラ #6版
satoshi256kbyte
1
230
Strategy for Finding a Problem for OSS: With Real Examples
kibitan
0
140
車輪の再発明をしよう!PHP で実装して学ぶ、Web サーバーの仕組みと HTTP の正体
h1r0
3
510
飯MCP
yusukebe
0
480
Everything Claude Code OSS詳細 — 5層構造の中身と導入方法
targe
0
160
安いハードウェアでVulkan
fadis
1
910
Featured
See All Featured
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
310
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
100
Un-Boring Meetings
codingconduct
0
250
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
180
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.1k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.4k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
250
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.4k
Bash Introduction
62gerente
615
210k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.4k
Believing is Seeing
oripsolob
1
110
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 で実 装されてるので、気になる実装があったら確認してみるとおもしろいかもしれませ ん!
ご清聴ありがとうございました