为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕田峪4524236 2023-03-29 15:22:02
众所周知,恐慌会产生一个堆栈跟踪到标准输出(Playground 链接):panic: runtime error: index out of rangegoroutine 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因为它显示了文件中导致恐慌的确切行。
查看完整描述

3 回答

?
繁星淼淼

TA贡献1775条经验 获得超11个赞

我们可以使用该runtime/debug包。


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)

}

印刷


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


查看完整回答
反对 回复 2023-03-29
?
HUX布斯

TA贡献1876条经验 获得超6个赞

创建一个日志文件以将堆栈跟踪添加到 stdout 或 stderr 的文件中。这将在文件中添加包括时间和错误行的数据。


package main


import (

    "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 操场上的工作示例



查看完整回答
反对 回复 2023-03-29
?
侃侃尔雅

TA贡献1801条经验 获得超15个赞

这是将恐慌转换为错误的解决方案,堆栈跟踪将像任何其他错误一样被记录


package main


import (

    "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 0

main.main.func1

    /tmp/sandbox2058999152/prog.go:17

runtime.gopanic

    /usr/local/go-faketime/src/runtime/panic.go:884

runtime.goPanicIndex

    /usr/local/go-faketime/src/runtime/panic.go:113

main.wrong

    /tmp/sandbox2058999152/prog.go:11

main.main

    /tmp/sandbox2058999152/prog.go:21

runtime.main

    /usr/local/go-faketime/src/runtime/proc.go:250

runtime.goexit

    /usr/local/go-faketime/src/runtime/asm_amd64.s:1594

Program exited.


查看完整回答
反对 回复 2023-03-29
  • 3 回答
  • 0 关注
  • 112 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信