Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the stacktrace of a panic (and store as a variable)

As we all know, panics produce a stacktrace to stdout (Playground link).:

panic: runtime error: index out of range goroutine 1 [running]: main.main()     /tmp/sandbox579134920/main.go:9 +0x20 

And it seems when you recover from a panic, recover() returns only an error which describes what caused the panic (Playground link).

runtime error: index out of range 

My question is, is it possible to store the stacktrace which is written to stdout? This provides much better debugging information than the string runtime error: index out of range because it shows the exact line in a file which caused the panic.

like image 628
hlin117 Avatar asked Aug 30 '18 18:08

hlin117


People also ask

How do you analyze a Stacktrace?

Analyze external stack tracesFrom the main menu, select Code | Analyze Stack Trace or Thread Dump. In the Analyze Stack Trace dialog that opens, paste the external stack trace or thread dump into the Put a stacktrace here: text area. Click OK. The stack trace is displayed in the Run tool window.

What is panic stack?

A panic is an exception in GoA panic stops the normal execution of a goroutine: When a program panics, it immediately starts to unwind the call stack. This continues until the program crashes and prints a stack trace, or until the built-in recover function is called.

How do you capture panic in Golang?

A panicking program can recover with the builtin recover() function: The recover function allows a program to manage behavior of a panicking goroutine. Suppose a function G defers a function D that calls recover and a panic occurs in a function on the same goroutine in which G is executing.

What is a Stacktrace error?

In simple terms, a stack trace is a list of the method calls that the application was in the middle of when an Exception was thrown. Simple Example. With the example given in the question, we can determine exactly where the exception was thrown in the application.


1 Answers

Like @Volker mentioned above, and what was posted as a comment, we can use the runtime/debug package.

package main  import (     "fmt"     "runtime/debug" )  func main() {     defer func() {         if r := recover(); r != nil {             fmt.Println("stacktrace from panic: \n" + string(debug.Stack()))         }     }()      var mySlice []int     j := mySlice[0]      fmt.Printf("Hello, playground %d", j) } 

prints

stacktrace from panic:  goroutine 1 [running]: runtime/debug.Stack(0x1042ff18, 0x98b2, 0xf0ba0, 0x17d048)     /usr/local/go/src/runtime/debug/stack.go:24 +0xc0 main.main.func1()     /tmp/sandbox973508195/main.go:11 +0x60 panic(0xf0ba0, 0x17d048)     /usr/local/go/src/runtime/panic.go:502 +0x2c0 main.main()     /tmp/sandbox973508195/main.go:16 +0x60 

Playground link.

like image 63
hlin117 Avatar answered Sep 29 '22 17:09

hlin117