golangでpanicをrecoverしたときにスタックトレースを表示する

golangではそもそもpanicしないようにコードを書くべきだしpanicが発生するならここで発生するのだと把握した上でコードを書くべきだ、という認識はある。とはいえ、golang書き始めてまもないので「念のために」recoverをコードに書いておきたかった。

具体的なコードは以下の通り。

https://play.golang.org/p/CxiR4j5Q6F_a

package main

import (
    "fmt"
    "log"
    "runtime"
)

func main() {
    log.SetFlags(log.LstdFlags | log.Lshortfile)
    defer func() {
        if err := recover(); err != nil {
            log.Printf("[ERROR] %s\n", err)
            for depth := 0; ; depth++ {
                _, file, line, ok := runtime.Caller(depth)
                if !ok {
                    break
                }
                log.Printf("======> %d: %v:%d", depth, file, line)
            }
        }
    }()

    a := []int{1, 2}
    fmt.Println(a[2])
}

結果は以下の通り。

2009/11/10 23:00:00 main.go:13: [ERROR] runtime error: index out of range
2009/11/10 23:00:00 main.go:19: ======> 0: /tmp/sandbox464635953/main.go:15
2009/11/10 23:00:00 main.go:19: ======> 1: /usr/local/go/src/runtime/asm_amd64p32.s:472
2009/11/10 23:00:00 main.go:19: ======> 2: /usr/local/go/src/runtime/panic.go:491
2009/11/10 23:00:00 main.go:19: ======> 3: /usr/local/go/src/runtime/panic.go:28
2009/11/10 23:00:00 main.go:19: ======> 4: /tmp/sandbox464635953/main.go:25
2009/11/10 23:00:00 main.go:19: ======> 5: /usr/local/go/src/runtime/proc.go:195
2009/11/10 23:00:00 main.go:19: ======> 6: /usr/local/go/src/runtime/asm_amd64p32.s:1040