如何获取恐慌的堆栈跟踪(并存储为变量)
How to get the stacktrace of a panic (and store as a variable)
众所周知,恐慌会产生到标准输出的堆栈跟踪 (Playground link)。:
panic: runtime error: index out of range
goroutine 1 [running]:
main.main()
/tmp/sandbox579134920/main.go:9 +0x20
似乎当您从恐慌中恢复过来时,recover()
returns 只有一个 error
描述了导致恐慌的原因 (Playground link)。
runtime error: index out of range
我的问题是,是否可以存储写入标准输出的堆栈跟踪?这提供了比字符串 runtime error: index out of range
更好的调试信息,因为它显示了文件中导致恐慌的确切行。
创建一个日志文件以将堆栈跟踪添加到 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()
}
上的工作示例
就像上面提到的@Volker,以及作为评论发布的内容,我们可以使用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
众所周知,恐慌会产生到标准输出的堆栈跟踪 (Playground link)。:
panic: runtime error: index out of range
goroutine 1 [running]:
main.main()
/tmp/sandbox579134920/main.go:9 +0x20
似乎当您从恐慌中恢复过来时,recover()
returns 只有一个 error
描述了导致恐慌的原因 (Playground link)。
runtime error: index out of range
我的问题是,是否可以存储写入标准输出的堆栈跟踪?这提供了比字符串 runtime error: index out of range
更好的调试信息,因为它显示了文件中导致恐慌的确切行。
创建一个日志文件以将堆栈跟踪添加到 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()
}
上的工作示例
就像上面提到的@Volker,以及作为评论发布的内容,我们可以使用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