2021-06-13 16:41:39 +00:00
|
|
|
package debug
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"runtime/debug"
|
|
|
|
"strings"
|
|
|
|
"syscall"
|
|
|
|
|
|
|
|
"github.com/ledgerwatch/erigon/log"
|
|
|
|
)
|
|
|
|
|
|
|
|
var sigc chan os.Signal
|
|
|
|
|
|
|
|
func GetSigC(sig *chan os.Signal) {
|
|
|
|
sigc = *sig
|
|
|
|
}
|
|
|
|
|
2021-07-12 06:39:44 +00:00
|
|
|
/*
|
|
|
|
var crashReportDir string
|
2021-06-13 16:41:39 +00:00
|
|
|
func prettyTime() string {
|
|
|
|
time := fmt.Sprintf("%v", time.Now())
|
|
|
|
return strings.Replace(time[:19], " ", "-", 1)
|
|
|
|
}
|
2021-06-14 06:35:01 +00:00
|
|
|
func CheckForCrashes(datadir string) {
|
|
|
|
crashReportDir = filepath.Join(datadir, "crashreports")
|
2021-06-22 10:09:45 +00:00
|
|
|
if _, err := os.Stat(crashReportDir); err != nil && os.IsNotExist(err) {
|
|
|
|
_ = os.MkdirAll(crashReportDir, 0755)
|
2021-06-14 06:35:01 +00:00
|
|
|
} else if err != nil {
|
2021-06-15 20:45:34 +00:00
|
|
|
log.Error("log_panic.go: CheckForCrashes", "error", err)
|
2021-06-13 16:41:39 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
f, err := os.Open(crashReportDir)
|
|
|
|
if err != nil {
|
2021-06-15 20:45:34 +00:00
|
|
|
log.Error("log_panic.go: CheckForCrashes", "error", err)
|
2021-06-13 16:41:39 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
fileInfo, err := f.ReadDir(-1)
|
|
|
|
if err != nil {
|
2021-06-15 20:45:34 +00:00
|
|
|
log.Error("log_panic.go: CheckForCrashes", "error", err)
|
2021-06-13 16:41:39 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
for _, v := range fileInfo {
|
|
|
|
if !v.IsDir() {
|
|
|
|
msg := fmt.Sprintf("Crashes From Previous Boots Detected. Find the stack trace in %v",
|
|
|
|
crashReportDir)
|
|
|
|
log.Warn(msg)
|
2021-06-22 10:09:45 +00:00
|
|
|
_ = f.Close()
|
2021-06-13 16:41:39 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-07-12 06:39:44 +00:00
|
|
|
*/
|
2021-06-22 10:09:45 +00:00
|
|
|
var panicReplacer = strings.NewReplacer("\n", " ", "\t", "", "\r", "")
|
|
|
|
|
|
|
|
// LogPanic - does log panic to logger and to <datadir>/crashreports then stops the process
|
|
|
|
func LogPanic() {
|
|
|
|
panicResult := recover()
|
|
|
|
if panicResult == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
stack := string(debug.Stack())
|
2021-07-12 06:39:44 +00:00
|
|
|
log.Error("catch panic", "err", panicResult, "stack", panicReplacer.Replace(stack))
|
|
|
|
//WriteStackTraceOnPanic(stack)
|
2021-06-22 10:09:45 +00:00
|
|
|
if sigc != nil {
|
|
|
|
sigc <- syscall.SIGINT
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ReportPanicAndRecover - does save panic to datadir/crashreports, bud doesn't log to logger and doesn't stop the process
|
|
|
|
// it returns recovered panic as error in format friendly for our logger
|
|
|
|
// common pattern of use - assign to named output param:
|
|
|
|
// func A() (err error) {
|
|
|
|
// defer func() { err = debug.ReportPanicAndRecover() }() // avoid crash because Erigon's core does many things
|
|
|
|
// }
|
2021-07-26 06:19:01 +00:00
|
|
|
func ReportPanicAndRecover(err error) error {
|
2021-06-22 10:09:45 +00:00
|
|
|
panicResult := recover()
|
|
|
|
if panicResult == nil {
|
2021-07-26 06:19:01 +00:00
|
|
|
return err
|
2021-06-22 10:09:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
stack := string(debug.Stack())
|
|
|
|
switch typed := panicResult.(type) {
|
|
|
|
case error:
|
|
|
|
err = fmt.Errorf("%w, trace: %s", typed, panicReplacer.Replace(stack))
|
|
|
|
default:
|
|
|
|
err = fmt.Errorf("%+v, trace: %s", typed, panicReplacer.Replace(stack))
|
2021-06-13 16:41:39 +00:00
|
|
|
}
|
2021-07-12 06:39:44 +00:00
|
|
|
//log.Error("panic", "err", panicResult, "stack", panicReplacer.Replace(stack))
|
|
|
|
//WriteStackTraceOnPanic(stack)
|
2021-06-13 16:41:39 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-07-12 06:39:44 +00:00
|
|
|
/*
|
2021-06-13 16:41:39 +00:00
|
|
|
func WriteStackTraceOnPanic(stack string) {
|
2021-06-14 06:35:01 +00:00
|
|
|
fileName := filepath.Join(crashReportDir, prettyTime()+".txt")
|
2021-06-13 16:41:39 +00:00
|
|
|
f, errFs := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
|
|
|
|
if errFs != nil {
|
2021-06-14 06:35:01 +00:00
|
|
|
log.Error("log_panic.go:WriteStackTraceOnPanic", "error", errFs)
|
2021-06-13 16:41:39 +00:00
|
|
|
f.Close()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
f.WriteString(stack)
|
|
|
|
f.Sync()
|
|
|
|
f.Close()
|
|
|
|
}
|
2021-07-12 06:39:44 +00:00
|
|
|
*/
|