Reputation: 808
is there a magic to identify where these mystery runtime error: invalid memory address or nil pointer dereference messages come from?
I tried setting breakpoint everywhere but no luck. It's not from any of my loggings - probably from some 3rd party library.
I also tried log.SetFlags(LstdFlags|Llongfile)
but doesn't change any verbosity.
I remember in some other languages + debugger there is always a way to find out when segmentation fault or null pointer reference exception takes place. Is there such magic for Golang?
Thanks!
Upvotes: 0
Views: 1194
Reputation: 52046
See defer, panic and recover on the go blog.
When running a deferred function, if the defer is executed in reaction to a panic, the stack still contains the state at panic time :
func withTrace() {
defer func() {
if r := recover(); r != nil {
fmt.Printf("caught panic: %s\n", r)
var stack [4096]byte
n := runtime.Stack(stack[:], false)
fmt.Printf("%s", stack[:n])
fmt.Println("\n// notice how 'trigger()' appears in the stack trace above,\n// even though the 'defer' is called from 'withTrace()'")
}
}()
fmt.Println("=== running withTrace() ...")
trigger()
}
// Output:
=== running withTrace() ...
caught panic: from trigger
goroutine 1 [running]:
main.withTrace.func1()
/tmp/sandbox2519976531/prog.go:31 +0x8b
panic({0x48a120, 0x4b8c60})
/usr/local/go-faketime/src/runtime/panic.go:884 +0x212
main.trigger(...)
/tmp/sandbox2519976531/prog.go:11
main.withTrace()
/tmp/sandbox2519976531/prog.go:38 +0x8c
main.main()
/tmp/sandbox2519976531/prog.go:43 +0x1c
// notice how 'trigger()' appears in the stack trace above,
// even though the 'defer' is called from 'withTrace()'
https://go.dev/play/p/MOapLmcSVVt
You would have to place this call to recover()
somewhere in the sequence of functions that execute your handlers.
In an http server, if you want to trace every possible panic in your handlers, a good place is a middleware set on all routes.
Upvotes: 2