如何在golang中捕获堆栈溢出错误

how to catch stack overflow error in golang

在golang中有什么方法可以捕获stack overflow错误吗?目前我正在使用 go recover() 做这个工作(下面的代码片段),看起来堆栈溢出错误无法被捕获。

defer func() {
            if x := recover(); x != nil {
                log.Error("In recover, cought error====================", x)
            }
        }()

fn(xxx)

您在输出中看到的是 "fatal error",而不是恐慌。

fatal error: stack overflow

您只能使用 recover() 从恐慌中恢复。堆栈溢出是运行时抛出的致命错误,它会导致进程打印堆栈跟踪并退出。

在 Golang 中有两种错误传播方式,一种是 return 错误,主要是函数相关的非致命错误。另一种是 panic,它通过函数调用堆栈传播,直到过程结束或到达 recover

Panic 是一个内置函数,它停止普通的控制流并开始恐慌。当函数 F 调用 panic 时,F 的执行停止,F 中的任何延迟函数正常执行,然后 F returns 到它的调用者。对于调用者,F 的行为就像调用 panic。该过程继续向上堆栈,直到当前 goroutine 中的所有函数都已 returned,此时程序崩溃。恐慌可以通过直接调用恐慌来启动。它们也可能是由运行时错误引起的,例如越界数组访问。

Recover 是一个内置函数,可以重新获得对 panicing goroutine 的控制。恢复仅在延迟函数内部有用。在正常执行期间,对 recover 的调用将 return nil 并且没有其他影响。如果当前 goroutine 处于 panicing 状态,则调用 recover 将捕获给 panic 的值并恢复正常执行。

如果你想忽略 panic 你可以调用 recover 并检查 panic 消息以查看 panic 消息是否属于预期类型 ok 忽略

以下是您的操作方法

//RecoverPanic recovers from panic given the message String
//if no message string is given it recovers from all panics
//Example:
//  defer RecoverPanic("stack overflow")
//The above satatement recovers any function from panic that happen
//due to Whosebug
func RecoverPanic(msg string) {
        if r := recover(); r != nil {
                if msg != "" {
                        if r != msg {
                                panic(r)
                        }
                }
        }
}

在此之后你可以调用,在函数调用的开始

funtion foo(){
    defer RecoverPanic("stack overflow")
    ......
}

有时 panic 无法处理,例如由于内存不足而尝试分配内存时出现 panic,不应尝试处理,因为处理自身的函数可能恐慌,因为没有内存来保存它的数据

通过使用 panic & recover,你可以实现在 golang 中捕获错误