如何获取恐慌的堆栈跟踪(并存储为变量)

众所周知,恐慌会产生一个堆栈跟踪到标准输出(Playground 链接):

panic: runtime error: index out of range

goroutine 1 [running]:

main.main()

    /tmp/sandbox579134920/main.go:9 +0x20

似乎当您从恐慌中恢复过来时,recover()只会返回一个error描述导致恐慌的原因(Playground 链接)。

runtime error: index out of range

我的问题是,是否可以存储写入标准输出的堆栈跟踪?这提供了比字符串更好的调试信息,runtime error: index out of range因为它显示了文件中导致恐慌的确切行。


慕田峪4524236
浏览 125回答 3
3回答

繁星淼淼

我们可以使用该runtime/debug包。package mainimport (    "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)}印刷stacktrace from panic: goroutine 1 [running]:runtime/debug.Stack(0x1042ff18, 0x98b2, 0xf0ba0, 0x17d048)    /usr/local/go/src/runtime/debug/stack.go:24 +0xc0main.main.func1()    /tmp/sandbox973508195/main.go:11 +0x60panic(0xf0ba0, 0x17d048)    /usr/local/go/src/runtime/panic.go:502 +0x2c0main.main()    /tmp/sandbox973508195/main.go:16 +0x60

HUX布斯

创建一个日志文件以将堆栈跟踪添加到 stdout 或 stderr 的文件中。这将在文件中添加包括时间和错误行的数据。package mainimport (    "log"    "os"    "runtime/debug")func main() {    defer func() {        if r := recover(); r != nil {            log.Println(string(debug.Stack()))        }    }()    //create your file with desired read/write permissions    f, err := os.OpenFile("filename", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)    if err != nil {        log.Println(err)    }    //set output of logs to f    log.SetOutput(f)    var mySlice []int    j := mySlice[0]    log.Println("Hello, playground %d", j)    //defer to close when you're done with it, not because you think it's idiomatic!    f.Close()}Go 操场上的工作示例

侃侃尔雅

这是将恐慌转换为错误的解决方案,堆栈跟踪将像任何其他错误一样被记录package mainimport (    "fmt"    "github.com/pkg/errors")func wrong() int {    var mySlice []int    return mySlice[0]}func main() {    defer func() {        if r := recover(); r != nil {            fmt.Printf("Error: %+v", errors.New(fmt.Sprintf("%v", r)))        }    }()    fmt.Printf("Hello, playground %d", wrong())}去游乐场输出Error: runtime error: index out of range [0] with length 0main.main.func1    /tmp/sandbox2058999152/prog.go:17runtime.gopanic    /usr/local/go-faketime/src/runtime/panic.go:884runtime.goPanicIndex    /usr/local/go-faketime/src/runtime/panic.go:113main.wrong    /tmp/sandbox2058999152/prog.go:11main.main    /tmp/sandbox2058999152/prog.go:21runtime.main    /usr/local/go-faketime/src/runtime/proc.go:250runtime.goexit    /usr/local/go-faketime/src/runtime/asm_amd64.s:1594Program exited.
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go