関連記事
GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ
概要
以下、自分用のメモです。
パニック時の出力の詳細度を設定する環境変数に GOTRACEBACK があります。
runtimeパッケージ のところに記載があり、設定出来る値について書かれています。
Go 1.24の時点で以下の設定値がありますね。
- none
- single
- all
- system
- crach
- wer
single がデフォルト値です。
環境変数なので通常は
$ GOTRACEBACK=all ./app
のように指定して実行するのですが、プログラムからも debug.SetTraceback() で設定出来ます。
試してみた
main.go
2秒したらパニックするプログラムを用意。
/* GOTRACEBACKの値をプログラムから設定するサンプル GOTRACEBACKは、Goのプログラムがパニックを起こした際の出力の詳細度を制御する環境変数。 プログラムからも設定することが可能で ```runtime/debug.SetTraceback()``` で設定できる。 debug.SetTraceback("all") 指定出来る値として - none - single (デフォルト) - all - system - crach - wer がある。 # REFERENCES - https://pkg.go.dev/runtime/debug#SetTraceback - https://pkg.go.dev/runtime#hdr-Environment_Variables - https://go.dev/doc/godebug */ package main import ( "flag" "fmt" "runtime/debug" "sync" "time" ) type ( Args struct { Traceback string } ) var ( args Args ) func init() { flag.StringVar(&args.Traceback, "traceback", "single", "GOTRACEBACK (none, single, all, system, crach, wer)") } func main() { flag.Parse() if args.Traceback == "" { args.Traceback = "single" } debug.SetTraceback(args.Traceback) if err := run(); err != nil { panic(err) } } func run() error { // // 2秒経過後に意図的にパニックさせる // ch := make(chan int) wg := sync.WaitGroup{} wg.Add(3) go func(ch chan<- int) { defer wg.Done() for i := range 100 { ch <- i time.Sleep(500 * time.Millisecond) } }(ch) go func(ch <-chan int) { defer wg.Done() for i := range ch { fmt.Println(i) } }(ch) go func(ch chan<- int) { defer wg.Done() defer close(ch) time.Sleep(2 * time.Second) }(ch) wg.Wait() return nil }
Taskfile.yml
# https://taskfile.dev version: '3' vars: APP_NAME: app tasks: default: cmds: - task: clean - task: run install-panicparse: cmds: - go install github.com/maruel/panicparse/v2/cmd/pp@latest status: - which pp clean: cmds: - rm -f ./{{.APP_NAME}}{{exeExt}} status: - test ! -f ./{{.APP_NAME}}{{exeExt}} build: cmds: - go build -o {{.APP_NAME}}{{exeExt}} . run: deps: [ build, install-panicparse ] cmds: - for: [ 'none', 'single', 'all', 'system', 'crach', 'wer' ] cmd: ./{{.APP_NAME}}{{exeExt}} -traceback {{.ITEM}} |& pp ignore_error: true
shell
実行すると以下のように出力されます。設定値ごとに出力される情報の増減がありますね。
$ task task: [clean] rm -f ./app task: [build] go build -o app . task: Task "install-panicparse" is up to date task: [run] ./app -traceback none |& pp 0 1 2 3 panic: send on closed channel To see all goroutines, visit https://github.com/maruel/panicparse#gotraceback 1: running [Created by main.run in goroutine 1 @ main.go:71] main main.go:74 run.func1(0xc000096070) task: [run] ./app -traceback single |& pp 0 1 2 3 panic: send on closed channel To see all goroutines, visit https://github.com/maruel/panicparse#gotraceback 1: running [Created by main.run in goroutine 1 @ main.go:71] main main.go:74 run.func1(0xc000096070) task: [run] ./app -traceback all |& pp 0 1 2 3 panic: send on closed channel 1: running [Created by main.run in goroutine 1 @ main.go:71] main main.go:74 run.func1(0xc000096070) 1: runnable sync sema.go:110 runtime_SemacquireWaitGroup(*uint32(#1)) sync waitgroup.go:118 (*WaitGroup).Wait(*WaitGroup(#2)) main main.go:90 run() main main.go:57 main() task: [run] ./app -traceback system |& pp 0 1 2 3 panic: send on closed channel goroutine 18 gp=0xc000102540 m=0 mp=0x5746c0 [running]: panic({0x4ab820?, 0x4e8710?}) /home/gitpod/go/src/runtime/panic.go:811 +0x168 fp=0xc0000646d8 sp=0xc000064628 pc=0x468728 runtime.chansend(0xc000116070, 0xc000064798, 0x1, 0xc000102540?) /home/gitpod/go/src/runtime/chan.go:226 +0x55e fp=0xc000064748 sp=0xc0000646d8 pc=0x40b73e runtime.chansend1(0x1dcd6500?, 0x0?) /home/gitpod/go/src/runtime/chan.go:161 +0x17 fp=0xc000064778 sp=0xc000064748 pc=0x40b1d7 main.run.func1(0xc000116070) /workspace/try-golang/examples/singleapp/debug_settraceback/main.go:74 +0x5f fp=0xc0000647c8 sp=0xc000064778 pc=0x49c83f main.run.gowrap1() /workspace/try-golang/examples/singleapp/debug_settraceback/main.go:77 +0x24 fp=0xc0000647e0 sp=0xc0000647c8 pc=0x49c7a4 runtime.goexit({}) /home/gitpod/go/src/runtime/asm_amd64.s:1700 +0x1 fp=0xc0000647e8 sp=0xc0000647e0 pc=0x46f441 created by main.run in goroutine 1 /workspace/try-golang/examples/singleapp/debug_settraceback/main.go:71 +0xd1 goroutine 1 gp=0xc000002380 m=nil [runnable]: runtime.Gosched(...) /home/gitpod/go/src/runtime/proc.go:364 runtime.main() /home/gitpod/go/src/runtime/proc.go:299 +0x313 fp=0xc000120fe0 sp=0xc000120f50 pc=0x43a353 runtime.goexit({}) /home/gitpod/go/src/runtime/asm_amd64.s:1700 +0x1 fp=0xc000120fe8 sp=0xc000120fe0 pc=0x46f441 goroutine 2 gp=0xc0000028c0 m=nil [force gc (idle)]: runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?) /home/gitpod/go/src/runtime/proc.go:435 +0xce fp=0xc000068fa8 sp=0xc000068f88 pc=0x468b4e runtime.goparkunlock(...) /home/gitpod/go/src/runtime/proc.go:441 runtime.forcegchelper() /home/gitpod/go/src/runtime/proc.go:348 +0xb3 fp=0xc000068fe0 sp=0xc000068fa8 pc=0x43a613 runtime.goexit({}) /home/gitpod/go/src/runtime/asm_amd64.s:1700 +0x1 fp=0xc000068fe8 sp=0xc000068fe0 pc=0x46f441 created by runtime.init.7 in goroutine 1 /home/gitpod/go/src/runtime/proc.go:336 +0x1a goroutine 3 gp=0xc000002e00 m=nil [GC sweep wait]: runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?) /home/gitpod/go/src/runtime/proc.go:435 +0xce fp=0xc000069780 sp=0xc000069760 pc=0x468b4e runtime.goparkunlock(...) /home/gitpod/go/src/runtime/proc.go:441 runtime.bgsweep(0xc00001e080) /home/gitpod/go/src/runtime/mgcsweep.go:276 +0x94 fp=0xc0000697c8 sp=0xc000069780 pc=0x4261b4 runtime.gcenable.gowrap1() /home/gitpod/go/src/runtime/mgc.go:204 +0x25 fp=0xc0000697e0 sp=0xc0000697c8 pc=0x41a8e5 runtime.goexit({}) /home/gitpod/go/src/runtime/asm_amd64.s:1700 +0x1 fp=0xc0000697e8 sp=0xc0000697e0 pc=0x46f441 created by runtime.gcenable in goroutine 1 /home/gitpod/go/src/runtime/mgc.go:204 +0x66 goroutine 4 gp=0xc000002fc0 m=nil [GC scavenge wait]: runtime.gopark(0xc00001e080?, 0x4e7c80?, 0x1?, 0x0?, 0xc000002fc0?) /home/gitpod/go/src/runtime/proc.go:435 +0xce fp=0xc000069f78 sp=0xc000069f58 pc=0x468b4e runtime.goparkunlock(...) /home/gitpod/go/src/runtime/proc.go:441 runtime.(*scavengerState).park(0x5738e0) /home/gitpod/go/src/runtime/mgcscavenge.go:425 +0x49 fp=0xc000069fa8 sp=0xc000069f78 pc=0x423c69 runtime.bgscavenge(0xc00001e080) /home/gitpod/go/src/runtime/mgcscavenge.go:653 +0x3c fp=0xc000069fc8 sp=0xc000069fa8 pc=0x4241dc runtime.gcenable.gowrap2() /home/gitpod/go/src/runtime/mgc.go:205 +0x25 fp=0xc000069fe0 sp=0xc000069fc8 pc=0x41a885 runtime.goexit({}) /home/gitpod/go/src/runtime/asm_amd64.s:1700 +0x1 fp=0xc000069fe8 sp=0xc000069fe0 pc=0x46f441 created by runtime.gcenable in goroutine 1 /home/gitpod/go/src/runtime/mgc.go:205 +0xa5 goroutine 17 gp=0xc000102380 m=nil [finalizer wait]: runtime.gopark(0x593ea0?, 0x490013?, 0x78?, 0x86?, 0x412b1e?) /home/gitpod/go/src/runtime/proc.go:435 +0xce fp=0xc000068630 sp=0xc000068610 pc=0x468b4e runtime.runfinq() /home/gitpod/go/src/runtime/mfinal.go:196 +0x107 fp=0xc0000687e0 sp=0xc000068630 pc=0x4198a7 runtime.goexit({}) /home/gitpod/go/src/runtime/asm_amd64.s:1700 +0x1 fp=0xc0000687e8 sp=0xc0000687e0 pc=0x46f441 created by runtime.createfing in goroutine 1 /home/gitpod/go/src/runtime/mfinal.go:166 +0x3d task: [run] ./app -traceback crach |& pp 0 1 2 3 panic: send on closed channel 1: running [Created by main.run in goroutine 1 @ main.go:71] main main.go:74 run.func1(0xc000116070) 1: runnable sync sema.go:110 runtime_SemacquireWaitGroup(*uint32(#2)) sync waitgroup.go:118 (*WaitGroup).Wait(*WaitGroup(#1)) main main.go:90 run() main main.go:57 main() task: [run] ./app -traceback wer |& pp 0 1 2 3 panic: send on closed channel 1: running [Created by main.run in goroutine 1 @ main.go:71] main main.go:74 run.func1(0xc000096070) 1: runnable sync sema.go:110 runtime_SemacquireWaitGroup(*uint32(#1)) sync waitgroup.go:118 (*WaitGroup).Wait(*WaitGroup(#2)) main main.go:90 run() main main.go:57 main()
参考情報
Goのおすすめ書籍
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。