1. 程式人生 > >golang捕獲panic

golang捕獲panic

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資訊的。