您的位置:首页 > 编程语言 > Go语言

golang捕获panic

2016-02-28 21:40 651 查看
golang当中panic的时候如果启动的goroutine比较多,刷的信息满屏都是,在终端工具上因为刷的信息太多,找不到前边的信息,因此很有必要程序自己捕获panic,并且将错误信息输出到文件当中,以便定位排查问题。

以下是一段捕获panic的代码

package main

import (
"fmt"
"os"
"runtime/debug"
"time"
)

func PanicHandler() {
exeName := os.Args[0] //获取程序名称

now := time.Now()  //获取当前时间
pid := os.Getpid() //获取进程ID

time_str := now.Format("20060102150405")                          //设定时间格式
fname := fmt.Sprintf("%s-%d-%s-dump.log", exeName, pid, time_str) //保存错误信息文件名:程序名-进程ID-当前时间(年月日时分秒)
fmt.Println("dump to file ", fname)

f, err := os.Create(fname)
if err != nil {
return
}
defer f.Close()

if err := recover(); err != nil {
f.WriteString(fmt.Sprintf("%v\r\n", err)) //输出panic信息
f.WriteString("========\r\n")
}

f.WriteString(string(debug.Stack())) //输出堆栈信息
}


以下是测试程序,这里我们测试除数为0的异常

package main

import (
"fmt"
//"sync"
)

func test_panic() {
n := 0
i := 5 / n
fmt.Println(i)
}

func main() {
defer PanicHandler()
test_panic()

/*
var wg sync.WaitGroup

wg.Add(1)
go func() {
defer PanicHandler()
test_panic()
wg.Done()
}()

wg.Wait()
*/
}


捕获的错误信息如下:

runtime error: integer divide by zero
========
F:/MyProject/Go/src/panictest/panicHandler.go:31 (0x4017c2)
PanicHandler: f.WriteString(string(debug.Stack())) //输出堆栈信息
c:/go/src/runtime/asm_amd64.s:437 (0x4543e5)
call32: CALLFN(·call32, 32)
c:/go/src/runtime/panic.go:423 (0x4291f7)
gopanic: reflectcall(nil, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
c:/go/src/runtime/panic.go:24 (0x427740)
panicdivide: panic(divideError)
c:/go/src/runtime/signal_windows.go:166 (0x43a31f)
sigpanic: panicdivide()
F:/MyProject/Go/src/panictest/main.go:10 (0x401073)
test_panic: i := 5 / n
F:/MyProject/Go/src/panictest/main.go:16 (0x40119c)
main: test_panic()
c:/go/src/runtime/proc.go:111 (0x42b78e)
main: main_main()
c:/go/src/runtime/asm_amd64.s:1721 (0x456821)
goexit: BYTE    $0x90  // NOP


至此获取错误并且存储的功能已经实现。

最后注意,如果是启动的多goroutine,需要在每个goroutine执行函数的时候,写上
defer PanicHandler()
否则的话是捕获不到其他goroutine当中的painc信息的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  golang