When recovering from panic in golang, I have often found myself troubled by potentially not knowing where the error originated...
This was because the stack doesn't get passed along with the message when you recover... or so I thought.
Go's runtime actually handles recovery from panic in an interesting way. Stack trace wise, it allows deferred functions the ability to call debug.Stack()
as if from the location of the panic.
for example:
package main
import (
"log"
"runtime/debug"
)
func main() {
defer func() {
if e := recover(); e != nil {
log.Printf("%s: %s", e, debug.Stack())
}
}()
f1()
}
func f1() {
f2()
}
func f2() {
f3()
}
func f3() {
panic("some error")
}
the stack trace output from the above code produces the following.
2021/09/13 22:00:07 some error: goroutine 1 [running]:
runtime/debug.Stack(0xc00009bdb8, 0x4acd60, 0x4e5168)
/home/rustysysdev/go/src/runtime/debug/stack.go:24 +0x9f
main.main.func1()
/home/rustysysdev/Documents/panic-test/cmd/panic/main.go:11 +0x5b
panic(0x4acd60, 0x4e5168)
/home/rustysysdev/go/src/runtime/panic.go:965 +0x1b9
main.f3(...)
/home/rustysysdev/Documents/panic-test/cmd/panic/main.go:27
main.f2(...)
/home/rustysysdev/Documents/panic-test/cmd/panic/main.go:23
main.f1(...)
/home/rustysysdev/Documents/panic-test/cmd/panic/main.go:19
main.main()
/home/rustysysdev/Documents/panic-test/cmd/panic/main.go:15 +0x5e
this is very useful for troubleshooting and I feel stupid only figuring this out now. XD
source: https://groups.google.com/g/golang-nuts/c/MB8GyW5j2UY
Top comments (1)
Didn't know this existed either... Good find!