Go语言捕获fatal错误,程序异常退出,致命错误
发布时间:2022-09-30, 01:29:38 分类:Go | 编辑 off 网址 | 辅助
正文 2430字数 190,038阅读
程序异常退出,如何通过Go语言捕获fatal错误?
这个问题我们可以通过对 Go 语言捕获错误的功能进行排查和整理。一般情况下,采用defer func(){recover() …} 类似的函数捕获程序中的错误,但是 recover() 函数在以下三种情况下是捕获不到对应的异常:
1.新运行了一个子协程,如果子协程中出现 panic 错误,是无法捕获的;
2.如果在程序中直接 os.Exit(0),对应的 defer 函数也不会运行,整个程序直接退出;
3.如果发生致命错误,recover() 无法捕获,例如以下的代码,并不能被捕获到。
defer func() {
err := recover()
if err != nil {
fmt.Print("err=", err)
}
}()
a := "hello world"
sh := (*reflect.StringHeader)(unsafe.Pointer(&a))
bh := reflect.SliceHeader{
Data: sh.Data,
Len: sh.Len,
Cap: sh.Len,
}
b := *(*[]byte)(unsafe.Pointer(&bh))
b[0] = 'H'
Run code
Cut to clipboard
运行过程中程序会直接出现一个致命异常,导致整个程序崩溃退出。
但是该种情况下,无法写入到日志,因此在程序运行中只有通过控制台才能看到对应的日志。针对此种情况,需要对代码进行处理。
在 Windows 系统中,修改的代码如下:
package elog
import (
"os"
"syscall"
)
var (
kernel32 = syscall.MustLoadDLL("kernel32.dll")
procSetStdHandle = kernel32.MustFindProc("SetStdHandle")
)
func setStdHandle(stdhandle int32, handle syscall.Handle) error {
r0, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0)
if r0 == 0 {
if e1 != 0 {
return error(e1)
}
return syscall.EINVAL
}
return nil
}
// RedirectStderr to the file passed in
func RedirectStderr() (err error) {
logFile, err := os.OpenFile("./test-error.log", os.O_WRONLY|os.O_CREATE|os.O_SYNC|os.O_APPEND, 0644)
if err != nil {
return
}
err = setStdHandle(syscall.STD_ERROR_HANDLE, syscall.Handle(logFile.Fd()))
if err != nil {
return
}
// SetStdHandle does not affect prior references to stderr
os.Stderr = logFile
return
}
Run code
Cut to clipboard
在 Linux 系统中,修改的代码如下:
package elog
import (
"os"
"syscall"
)
// RedirectStderr to the file passed in
func RedirectStderr() (err error) {
logFile, err := os.OpenFile("./test-error.log", os.O_WRONLY|os.O_CREATE|os.O_SYNC|os.O_APPEND, 0644)
if err != nil {
return
}
err = syscall.Dup3(int(logFile.Fd()), int(os.Stderr.Fd()),0)
if err != nil {
return
}
return
}
Run code
Cut to clipboard
main函数中调用代码
elog.RedirectStderr()
Run code
Cut to clipboard
最终如果出现 fatal 代码,就写入到 test-error.log 中
原创声明,本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
原文地址:https://cloud.tencent.com/developer/article/1902875#undefined
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原文地址:https://cloud.tencent.com/developer/article/1902875#undefined
如有侵权,请联系 cloudcommunity@tencent.com 删除。
(支付宝)给作者钱财以资鼓励 (微信)→
有过 1 条评论 »
在cmd中输入:
go env -w GOPROXY=https://goproxy.cn
安装GO语言相关插件
在vscode中安装GO语言相关插件的时候,报错:
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.