Adding upstream version 3.10.8.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
37e9b6d587
commit
03bfe4079e
356 changed files with 28857 additions and 0 deletions
98
util/panic.go
Normal file
98
util/panic.go
Normal file
|
@ -0,0 +1,98 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var packagePrefix string
|
||||
|
||||
func init() {
|
||||
_, filename, _, _ := runtime.Caller(0)
|
||||
packagePrefix = strings.TrimSuffix(filename, "util/panic.go")
|
||||
if packagePrefix == filename {
|
||||
// in case the source code file is moved, we can not trim the suffix, the code above should also be updated.
|
||||
panic("unable to detect correct package prefix, please update file: " + filename)
|
||||
}
|
||||
}
|
||||
|
||||
func getStack() string {
|
||||
callersLength := 5
|
||||
var callers []uintptr
|
||||
var callersCount int
|
||||
for {
|
||||
callers = make([]uintptr, callersLength)
|
||||
callersCount = runtime.Callers(4, callers)
|
||||
if callersCount <= 0 {
|
||||
panic("runtime.Callers <= 0")
|
||||
}
|
||||
if callersCount >= callersLength {
|
||||
callersLength *= 2
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
callers = callers[:callersCount]
|
||||
frames := runtime.CallersFrames(callers)
|
||||
stack := make([]string, 0, 10)
|
||||
for {
|
||||
frame, more := frames.Next()
|
||||
if strings.HasPrefix(frame.File, packagePrefix) {
|
||||
file := strings.TrimPrefix(frame.File, packagePrefix)
|
||||
if file == "util/panic.go" || file == "util/terminate.go" && more {
|
||||
continue
|
||||
}
|
||||
var function string
|
||||
dot := strings.LastIndex(frame.Function, ".")
|
||||
if dot >= 0 {
|
||||
function = frame.Function[dot+1:]
|
||||
}
|
||||
stack = append(stack, fmt.Sprintf("%s:%d:%s", file, frame.Line, function))
|
||||
}
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
}
|
||||
return strings.Join(stack, "\n") + "\n"
|
||||
}
|
||||
|
||||
type PanicError interface {
|
||||
error
|
||||
Stack() string
|
||||
}
|
||||
|
||||
type panicError struct {
|
||||
message string
|
||||
stack string
|
||||
}
|
||||
|
||||
func (o panicError) Error() string { return o.message }
|
||||
func (o panicError) Stack() string { return o.stack }
|
||||
|
||||
func PanicToError(fun func()) (err PanicError) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
recoveredErr, ok := r.(error)
|
||||
var message string
|
||||
if ok {
|
||||
message = recoveredErr.Error()
|
||||
}
|
||||
err = panicError{
|
||||
message: message,
|
||||
stack: getStack(),
|
||||
}
|
||||
if !ok {
|
||||
panic(r)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
fun()
|
||||
|
||||
return err
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue