Go 1.25でアップデートされたpanic出力の変更内容を追ってみた
この記事は、Go Advent Calendar 2025 の 20 日目の記事です。
はじめに
Go 1.25 で panic 出力のフォーマットが変更されました。
すでに至るところで紹介されている内容かつ軽微な変更ではありますが、この記事では実際にソースコードを追いかけてみた内容を紹介します。
変更内容の確認
提案された issue はこちらです。
Go 1.25 以前は同じ panic が複数発生すると、以下のように出力されていました。
panic: PANIC [recovered]
panic: PANIC
Go 1.25 以降では、以下のように出力されるようになります。
panic: PANIC [recovered, repanicked]
試してみた
issue の例を試してみます。
package main
import (
"testing"
)
func Test(t *testing.T) {
panic("oops")
}
Go 1.24 の出力は以下のとおりです。
panic: oops が 2 回出力されています。
go1.24.0 test -v ./sample_test.go
=== RUN Test
--- FAIL: Test (0.00s)
panic: oops [recovered]
panic: oops
goroutine 3 [running]:
testing.tRunner.func1.2({0x1022a8620, 0x1022d79f0})
/path/to/sdk/go1.24.0/src/testing/testing.go:1734 +0x1ac
testing.tRunner.func1()
/path/to/sdk/go1.24.0/src/testing/testing.go:1737 +0x334
panic({0x1022a8620?, 0x1022d79f0?})
/path/to/sdk/go1.24.0/src/runtime/panic.go:787 +0x124
command-line-arguments.Test(0x14000003500?)
/path/to/go/src/sample/sample_test.go:8 +0x2c
testing.tRunner(0x14000003500, 0x1022d6fa8)
/path/to/sdk/go1.24.0/src/testing/testing.go:1792 +0xe4
created by testing.(*T).Run in goroutine 1
/path/to/sdk/go1.24.0/src/testing/testing.go:1851 +0x374
FAIL command-line-arguments 0.619s
FAIL
報告されている通り testingパッケージの tRunner 関数内で panic を recover した後に再度 panic しているためです。
上記コードは Go 1.25 でも同様です。
変更箇所の確認
panic メッセージを作成するフローで、同じ panic が連続して発生していないかチェックするようになりました。
efaceOf で型情報とデータ情報を取得できるように変換して比較しています。
上記の比較でrepanickedフラグが true の場合、 panic メッセージに [recovered, repanicked] を追加するようになりました。
試してみた
同じテストコードで確認します。
Go 1.25 の出力は以下のとおりです。
panic: oops が 1 回出力されています。repanickedで重複したログ出力が抑制されていることがわかります。
go1.25.0 test -v ./sample_test.go
=== RUN Test
--- FAIL: Test (0.00s)
panic: oops [recovered, repanicked]
goroutine 34 [running]:
testing.tRunner.func1.2({0x100c30d20, 0x100c61710})
/path/to/sdk/go1.25.0/src/testing/testing.go:1872 +0x190
testing.tRunner.func1()
/path/to/sdk/go1.25.0/src/testing/testing.go:1875 +0x31c
panic({0x100c30d20?, 0x100c61710?})
/path/to/sdk/go1.25.0/src/runtime/panic.go:783 +0x120
command-line-arguments.Test(0x14000126380?)
/path/to/go/src/sample/sample_test.go:8 +0x2c
testing.tRunner(0x14000126380, 0x100c60c00)
/path/to/sdk/go1.25.0/src/testing/testing.go:1934 +0xc8
created by testing.(*T).Run in goroutine 1
/path/to/sdk/go1.25.0/src/testing/testing.go:1997 +0x364
FAIL command-line-arguments 0.484s
FAIL
余談:reraisedからrepanickedに変更された
issue と最初の提案では[recovered, reraised] としていたのが、rsc さんからのコメントで [recovered, repanicked] に変更されました。
raised は例外のための用語ですが、Go には例外がないため、repanicked の方が適切という理由からです。
余談: Go 1.25 では recover されていないのに [recovered, repanicked] と表示されていた問題が修正された
ここで repanicked フラグのみチェックして、[recovered, repanicked]と表示される問題が報告されました。
現時点で確認できる Go 1.26 Release Candidate 1 で修正されていることが確認できます。
おわりに
Go 1.25 で追加された panic 出力フォーマットの変更内容と、その動作を検証コードを通じて理解を深めることができました。
最後の余談の話に関しては、Go本体へのコントリビュートチャンスの余地を感じたので、引き続き気になったときにリリースノートの確認は続けていこうと思います。
Discussion