Wednesday, July 15, 2020

Using GOTRACEBACK to Control the Panic Stack Trace





When a GO application is crashing due to a critical error, a stack trace of the panic producing GO routine is printed.
For example, the following application produces a SIGSEGV signal (memory access violation).


func main() {
go func() {
for {
fmt.Println("go routine")
time.Sleep(time.Second)
var i *int
*i=0
}
}()

for {
fmt.Println("main func")
time.Sleep(time.Second)
}
}


Running this code displays the following output:


main func
go routine
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x48d294]

goroutine 18 [running]:
main.main.func1()
        /home/alon/git/panic/main.go:14 +0x84
created by main.main
        /home/alon/git/panic/main.go:9 +0x39


We can see the stack trace of the GO routine to blame.

But what about other GO routines?

To view more details, we need to use the GOTRACEBACK environment variable.
When the GOTRACEBACK is not set, it is defaulted to the value single.
This means we get the stack trace of the current running GO routine.

To get the stack trace of all of the application GO routine, we need to set the GOTRACEBACK environment variable to the value all. In such a case, the output of the application panic is the following:



main func
go routine
main func
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x48d294]

goroutine 18 [running]:
main.main.func1()
        /home/alon/git/panic/main.go:14 +0x84
created by main.main
        /home/alon/git/panic/main.go:9 +0x39

goroutine 1 [sleep]:
runtime.goparkunlock(...)
        /usr/local/go/src/runtime/proc.go:310
time.Sleep(0x3b9aca00)
        /usr/local/go/src/runtime/time.go:105 +0x157
main.main()
        /home/alon/git/panic/main.go:20 +0x9e


Now we can see the two GO routines.


Other possible values for the GOTRACEBACK environment variable are:
  • none - do not print any stack traces
  • system - print all the application GO routines stack traces as well as the GO runtime system GO routines stack traces
  • crash - same as system, but instead of exit with error code 2, triggers a core dump


Final Notes


I prefer changing the default of the GOTRACEBACK environment variable to all. In most cases, upon an application dump, you would need more information than jump the running GO routine, especially in a complex system.


No comments:

Post a Comment