272
vendor/github.com/ethereum/go-ethereum/internal/debug/api.go
generated
vendored
Normal file
272
vendor/github.com/ethereum/go-ethereum/internal/debug/api.go
generated
vendored
Normal file
@@ -0,0 +1,272 @@
|
||||
// Copyright 2016 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Package debug interfaces Go runtime debugging facilities.
|
||||
// This package is mostly glue code making these facilities available
|
||||
// through the CLI and RPC subsystem. If you want to use them from Go code,
|
||||
// use package runtime instead.
|
||||
package debug
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"runtime/pprof"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/hashicorp/go-bexpr"
|
||||
)
|
||||
|
||||
// Handler is the global debugging handler.
|
||||
var Handler = new(HandlerT)
|
||||
|
||||
// HandlerT implements the debugging API.
|
||||
// Do not create values of this type, use the one
|
||||
// in the Handler variable instead.
|
||||
type HandlerT struct {
|
||||
mu sync.Mutex
|
||||
cpuW io.WriteCloser
|
||||
cpuFile string
|
||||
traceW io.WriteCloser
|
||||
traceFile string
|
||||
}
|
||||
|
||||
// Verbosity sets the log verbosity ceiling. The verbosity of individual packages
|
||||
// and source files can be raised using Vmodule.
|
||||
func (*HandlerT) Verbosity(level int) {
|
||||
glogger.Verbosity(log.Lvl(level))
|
||||
}
|
||||
|
||||
// Vmodule sets the log verbosity pattern. See package log for details on the
|
||||
// pattern syntax.
|
||||
func (*HandlerT) Vmodule(pattern string) error {
|
||||
return glogger.Vmodule(pattern)
|
||||
}
|
||||
|
||||
// BacktraceAt sets the log backtrace location. See package log for details on
|
||||
// the pattern syntax.
|
||||
func (*HandlerT) BacktraceAt(location string) error {
|
||||
return glogger.BacktraceAt(location)
|
||||
}
|
||||
|
||||
// MemStats returns detailed runtime memory statistics.
|
||||
func (*HandlerT) MemStats() *runtime.MemStats {
|
||||
s := new(runtime.MemStats)
|
||||
runtime.ReadMemStats(s)
|
||||
return s
|
||||
}
|
||||
|
||||
// GcStats returns GC statistics.
|
||||
func (*HandlerT) GcStats() *debug.GCStats {
|
||||
s := new(debug.GCStats)
|
||||
debug.ReadGCStats(s)
|
||||
return s
|
||||
}
|
||||
|
||||
// CpuProfile turns on CPU profiling for nsec seconds and writes
|
||||
// profile data to file.
|
||||
func (h *HandlerT) CpuProfile(file string, nsec uint) error {
|
||||
if err := h.StartCPUProfile(file); err != nil {
|
||||
return err
|
||||
}
|
||||
time.Sleep(time.Duration(nsec) * time.Second)
|
||||
h.StopCPUProfile()
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartCPUProfile turns on CPU profiling, writing to the given file.
|
||||
func (h *HandlerT) StartCPUProfile(file string) error {
|
||||
h.mu.Lock()
|
||||
defer h.mu.Unlock()
|
||||
if h.cpuW != nil {
|
||||
return errors.New("CPU profiling already in progress")
|
||||
}
|
||||
f, err := os.Create(expandHome(file))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := pprof.StartCPUProfile(f); err != nil {
|
||||
f.Close()
|
||||
return err
|
||||
}
|
||||
h.cpuW = f
|
||||
h.cpuFile = file
|
||||
log.Info("CPU profiling started", "dump", h.cpuFile)
|
||||
return nil
|
||||
}
|
||||
|
||||
// StopCPUProfile stops an ongoing CPU profile.
|
||||
func (h *HandlerT) StopCPUProfile() error {
|
||||
h.mu.Lock()
|
||||
defer h.mu.Unlock()
|
||||
pprof.StopCPUProfile()
|
||||
if h.cpuW == nil {
|
||||
return errors.New("CPU profiling not in progress")
|
||||
}
|
||||
log.Info("Done writing CPU profile", "dump", h.cpuFile)
|
||||
h.cpuW.Close()
|
||||
h.cpuW = nil
|
||||
h.cpuFile = ""
|
||||
return nil
|
||||
}
|
||||
|
||||
// GoTrace turns on tracing for nsec seconds and writes
|
||||
// trace data to file.
|
||||
func (h *HandlerT) GoTrace(file string, nsec uint) error {
|
||||
if err := h.StartGoTrace(file); err != nil {
|
||||
return err
|
||||
}
|
||||
time.Sleep(time.Duration(nsec) * time.Second)
|
||||
h.StopGoTrace()
|
||||
return nil
|
||||
}
|
||||
|
||||
// BlockProfile turns on goroutine profiling for nsec seconds and writes profile data to
|
||||
// file. It uses a profile rate of 1 for most accurate information. If a different rate is
|
||||
// desired, set the rate and write the profile manually.
|
||||
func (*HandlerT) BlockProfile(file string, nsec uint) error {
|
||||
runtime.SetBlockProfileRate(1)
|
||||
time.Sleep(time.Duration(nsec) * time.Second)
|
||||
defer runtime.SetBlockProfileRate(0)
|
||||
return writeProfile("block", file)
|
||||
}
|
||||
|
||||
// SetBlockProfileRate sets the rate of goroutine block profile data collection.
|
||||
// rate 0 disables block profiling.
|
||||
func (*HandlerT) SetBlockProfileRate(rate int) {
|
||||
runtime.SetBlockProfileRate(rate)
|
||||
}
|
||||
|
||||
// WriteBlockProfile writes a goroutine blocking profile to the given file.
|
||||
func (*HandlerT) WriteBlockProfile(file string) error {
|
||||
return writeProfile("block", file)
|
||||
}
|
||||
|
||||
// MutexProfile turns on mutex profiling for nsec seconds and writes profile data to file.
|
||||
// It uses a profile rate of 1 for most accurate information. If a different rate is
|
||||
// desired, set the rate and write the profile manually.
|
||||
func (*HandlerT) MutexProfile(file string, nsec uint) error {
|
||||
runtime.SetMutexProfileFraction(1)
|
||||
time.Sleep(time.Duration(nsec) * time.Second)
|
||||
defer runtime.SetMutexProfileFraction(0)
|
||||
return writeProfile("mutex", file)
|
||||
}
|
||||
|
||||
// SetMutexProfileFraction sets the rate of mutex profiling.
|
||||
func (*HandlerT) SetMutexProfileFraction(rate int) {
|
||||
runtime.SetMutexProfileFraction(rate)
|
||||
}
|
||||
|
||||
// WriteMutexProfile writes a goroutine blocking profile to the given file.
|
||||
func (*HandlerT) WriteMutexProfile(file string) error {
|
||||
return writeProfile("mutex", file)
|
||||
}
|
||||
|
||||
// WriteMemProfile writes an allocation profile to the given file.
|
||||
// Note that the profiling rate cannot be set through the API,
|
||||
// it must be set on the command line.
|
||||
func (*HandlerT) WriteMemProfile(file string) error {
|
||||
return writeProfile("heap", file)
|
||||
}
|
||||
|
||||
// Stacks returns a printed representation of the stacks of all goroutines. It
|
||||
// also permits the following optional filters to be used:
|
||||
// - filter: boolean expression of packages to filter for
|
||||
func (*HandlerT) Stacks(filter *string) string {
|
||||
buf := new(bytes.Buffer)
|
||||
pprof.Lookup("goroutine").WriteTo(buf, 2)
|
||||
|
||||
// If any filtering was requested, execute them now
|
||||
if filter != nil && len(*filter) > 0 {
|
||||
expanded := *filter
|
||||
|
||||
// The input filter is a logical expression of package names. Transform
|
||||
// it into a proper boolean expression that can be fed into a parser and
|
||||
// interpreter:
|
||||
//
|
||||
// E.g. (eth || snap) && !p2p -> (eth in Value || snap in Value) && p2p not in Value
|
||||
expanded = regexp.MustCompile(`[:/\.A-Za-z0-9_-]+`).ReplaceAllString(expanded, "`$0` in Value")
|
||||
expanded = regexp.MustCompile("!(`[:/\\.A-Za-z0-9_-]+`)").ReplaceAllString(expanded, "$1 not")
|
||||
expanded = strings.ReplaceAll(expanded, "||", "or")
|
||||
expanded = strings.ReplaceAll(expanded, "&&", "and")
|
||||
log.Info("Expanded filter expression", "filter", *filter, "expanded", expanded)
|
||||
|
||||
expr, err := bexpr.CreateEvaluator(expanded)
|
||||
if err != nil {
|
||||
log.Error("Failed to parse filter expression", "expanded", expanded, "err", err)
|
||||
return ""
|
||||
}
|
||||
// Split the goroutine dump into segments and filter each
|
||||
dump := buf.String()
|
||||
buf.Reset()
|
||||
|
||||
for _, trace := range strings.Split(dump, "\n\n") {
|
||||
if ok, _ := expr.Evaluate(map[string]string{"Value": trace}); ok {
|
||||
buf.WriteString(trace)
|
||||
buf.WriteString("\n\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// FreeOSMemory forces a garbage collection.
|
||||
func (*HandlerT) FreeOSMemory() {
|
||||
debug.FreeOSMemory()
|
||||
}
|
||||
|
||||
// SetGCPercent sets the garbage collection target percentage. It returns the previous
|
||||
// setting. A negative value disables GC.
|
||||
func (*HandlerT) SetGCPercent(v int) int {
|
||||
return debug.SetGCPercent(v)
|
||||
}
|
||||
|
||||
func writeProfile(name, file string) error {
|
||||
p := pprof.Lookup(name)
|
||||
log.Info("Writing profile records", "count", p.Count(), "type", name, "dump", file)
|
||||
f, err := os.Create(expandHome(file))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
return p.WriteTo(f, 0)
|
||||
}
|
||||
|
||||
// expands home directory in file paths.
|
||||
// ~someuser/tmp will not be expanded.
|
||||
func expandHome(p string) string {
|
||||
if strings.HasPrefix(p, "~/") || strings.HasPrefix(p, "~\\") {
|
||||
home := os.Getenv("HOME")
|
||||
if home == "" {
|
||||
if usr, err := user.Current(); err == nil {
|
||||
home = usr.HomeDir
|
||||
}
|
||||
}
|
||||
if home != "" {
|
||||
p = home + p[1:]
|
||||
}
|
||||
}
|
||||
return filepath.Clean(p)
|
||||
}
|
||||
220
vendor/github.com/ethereum/go-ethereum/internal/debug/flags.go
generated
vendored
Normal file
220
vendor/github.com/ethereum/go-ethereum/internal/debug/flags.go
generated
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
// Copyright 2016 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package debug
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
_ "net/http/pprof" // nolint: gosec
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/ethereum/go-ethereum/internal/flags"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/metrics/exp"
|
||||
"github.com/fjl/memsize/memsizeui"
|
||||
"github.com/mattn/go-colorable"
|
||||
"github.com/mattn/go-isatty"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var Memsize memsizeui.Handler
|
||||
|
||||
var (
|
||||
verbosityFlag = &cli.IntFlag{
|
||||
Name: "verbosity",
|
||||
Usage: "Logging verbosity: 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail",
|
||||
Value: 3,
|
||||
Category: flags.LoggingCategory,
|
||||
}
|
||||
vmoduleFlag = &cli.StringFlag{
|
||||
Name: "vmodule",
|
||||
Usage: "Per-module verbosity: comma-separated list of <pattern>=<level> (e.g. eth/*=5,p2p=4)",
|
||||
Value: "",
|
||||
Category: flags.LoggingCategory,
|
||||
}
|
||||
logjsonFlag = &cli.BoolFlag{
|
||||
Name: "log.json",
|
||||
Usage: "Format logs with JSON",
|
||||
Category: flags.LoggingCategory,
|
||||
}
|
||||
backtraceAtFlag = &cli.StringFlag{
|
||||
Name: "log.backtrace",
|
||||
Usage: "Request a stack trace at a specific logging statement (e.g. \"block.go:271\")",
|
||||
Value: "",
|
||||
Category: flags.LoggingCategory,
|
||||
}
|
||||
debugFlag = &cli.BoolFlag{
|
||||
Name: "log.debug",
|
||||
Usage: "Prepends log messages with call-site location (file and line number)",
|
||||
Category: flags.LoggingCategory,
|
||||
}
|
||||
pprofFlag = &cli.BoolFlag{
|
||||
Name: "pprof",
|
||||
Usage: "Enable the pprof HTTP server",
|
||||
Category: flags.LoggingCategory,
|
||||
}
|
||||
pprofPortFlag = &cli.IntFlag{
|
||||
Name: "pprof.port",
|
||||
Usage: "pprof HTTP server listening port",
|
||||
Value: 6060,
|
||||
Category: flags.LoggingCategory,
|
||||
}
|
||||
pprofAddrFlag = &cli.StringFlag{
|
||||
Name: "pprof.addr",
|
||||
Usage: "pprof HTTP server listening interface",
|
||||
Value: "127.0.0.1",
|
||||
Category: flags.LoggingCategory,
|
||||
}
|
||||
memprofilerateFlag = &cli.IntFlag{
|
||||
Name: "pprof.memprofilerate",
|
||||
Usage: "Turn on memory profiling with the given rate",
|
||||
Value: runtime.MemProfileRate,
|
||||
Category: flags.LoggingCategory,
|
||||
}
|
||||
blockprofilerateFlag = &cli.IntFlag{
|
||||
Name: "pprof.blockprofilerate",
|
||||
Usage: "Turn on block profiling with the given rate",
|
||||
Category: flags.LoggingCategory,
|
||||
}
|
||||
cpuprofileFlag = &cli.StringFlag{
|
||||
Name: "pprof.cpuprofile",
|
||||
Usage: "Write CPU profile to the given file",
|
||||
Category: flags.LoggingCategory,
|
||||
}
|
||||
traceFlag = &cli.StringFlag{
|
||||
Name: "trace",
|
||||
Usage: "Write execution trace to the given file",
|
||||
Category: flags.LoggingCategory,
|
||||
}
|
||||
)
|
||||
|
||||
// Flags holds all command-line flags required for debugging.
|
||||
var Flags = []cli.Flag{
|
||||
verbosityFlag,
|
||||
vmoduleFlag,
|
||||
logjsonFlag,
|
||||
backtraceAtFlag,
|
||||
debugFlag,
|
||||
pprofFlag,
|
||||
pprofAddrFlag,
|
||||
pprofPortFlag,
|
||||
memprofilerateFlag,
|
||||
blockprofilerateFlag,
|
||||
cpuprofileFlag,
|
||||
traceFlag,
|
||||
}
|
||||
|
||||
var glogger *log.GlogHandler
|
||||
|
||||
func init() {
|
||||
glogger = log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false)))
|
||||
glogger.Verbosity(log.LvlInfo)
|
||||
log.Root().SetHandler(glogger)
|
||||
}
|
||||
|
||||
// Setup initializes profiling and logging based on the CLI flags.
|
||||
// It should be called as early as possible in the program.
|
||||
func Setup(ctx *cli.Context) error {
|
||||
var ostream log.Handler
|
||||
output := io.Writer(os.Stderr)
|
||||
if ctx.Bool(logjsonFlag.Name) {
|
||||
ostream = log.StreamHandler(output, log.JSONFormat())
|
||||
} else {
|
||||
usecolor := (isatty.IsTerminal(os.Stderr.Fd()) || isatty.IsCygwinTerminal(os.Stderr.Fd())) && os.Getenv("TERM") != "dumb"
|
||||
if usecolor {
|
||||
output = colorable.NewColorableStderr()
|
||||
}
|
||||
ostream = log.StreamHandler(output, log.TerminalFormat(usecolor))
|
||||
}
|
||||
glogger.SetHandler(ostream)
|
||||
|
||||
// logging
|
||||
verbosity := ctx.Int(verbosityFlag.Name)
|
||||
glogger.Verbosity(log.Lvl(verbosity))
|
||||
vmodule := ctx.String(vmoduleFlag.Name)
|
||||
glogger.Vmodule(vmodule)
|
||||
|
||||
debug := ctx.Bool(debugFlag.Name)
|
||||
if ctx.IsSet(debugFlag.Name) {
|
||||
debug = ctx.Bool(debugFlag.Name)
|
||||
}
|
||||
log.PrintOrigins(debug)
|
||||
|
||||
backtrace := ctx.String(backtraceAtFlag.Name)
|
||||
glogger.BacktraceAt(backtrace)
|
||||
|
||||
log.Root().SetHandler(glogger)
|
||||
|
||||
// profiling, tracing
|
||||
runtime.MemProfileRate = memprofilerateFlag.Value
|
||||
if ctx.IsSet(memprofilerateFlag.Name) {
|
||||
runtime.MemProfileRate = ctx.Int(memprofilerateFlag.Name)
|
||||
}
|
||||
|
||||
blockProfileRate := ctx.Int(blockprofilerateFlag.Name)
|
||||
Handler.SetBlockProfileRate(blockProfileRate)
|
||||
|
||||
if traceFile := ctx.String(traceFlag.Name); traceFile != "" {
|
||||
if err := Handler.StartGoTrace(traceFile); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if cpuFile := ctx.String(cpuprofileFlag.Name); cpuFile != "" {
|
||||
if err := Handler.StartCPUProfile(cpuFile); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// pprof server
|
||||
if ctx.Bool(pprofFlag.Name) {
|
||||
listenHost := ctx.String(pprofAddrFlag.Name)
|
||||
|
||||
port := ctx.Int(pprofPortFlag.Name)
|
||||
|
||||
address := fmt.Sprintf("%s:%d", listenHost, port)
|
||||
// This context value ("metrics.addr") represents the utils.MetricsHTTPFlag.Name.
|
||||
// It cannot be imported because it will cause a cyclical dependency.
|
||||
StartPProf(address, !ctx.IsSet("metrics.addr"))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func StartPProf(address string, withMetrics bool) {
|
||||
// Hook go-metrics into expvar on any /debug/metrics request, load all vars
|
||||
// from the registry into expvar, and execute regular expvar handler.
|
||||
if withMetrics {
|
||||
exp.Exp(metrics.DefaultRegistry)
|
||||
}
|
||||
http.Handle("/memsize/", http.StripPrefix("/memsize", &Memsize))
|
||||
log.Info("Starting pprof server", "addr", fmt.Sprintf("http://%s/debug/pprof", address))
|
||||
go func() {
|
||||
if err := http.ListenAndServe(address, nil); err != nil {
|
||||
log.Error("Failure in running pprof server", "err", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Exit stops all running profiles, flushing their output to the
|
||||
// respective file.
|
||||
func Exit() {
|
||||
Handler.StopCPUProfile()
|
||||
Handler.StopGoTrace()
|
||||
}
|
||||
28
vendor/github.com/ethereum/go-ethereum/internal/debug/loudpanic.go
generated
vendored
Normal file
28
vendor/github.com/ethereum/go-ethereum/internal/debug/loudpanic.go
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2016 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//go:build go1.6
|
||||
// +build go1.6
|
||||
|
||||
package debug
|
||||
|
||||
import "runtime/debug"
|
||||
|
||||
// LoudPanic panics in a way that gets all goroutine stacks printed on stderr.
|
||||
func LoudPanic(x interface{}) {
|
||||
debug.SetTraceback("all")
|
||||
panic(x)
|
||||
}
|
||||
25
vendor/github.com/ethereum/go-ethereum/internal/debug/loudpanic_fallback.go
generated
vendored
Normal file
25
vendor/github.com/ethereum/go-ethereum/internal/debug/loudpanic_fallback.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2016 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//go:build !go1.6
|
||||
// +build !go1.6
|
||||
|
||||
package debug
|
||||
|
||||
// LoudPanic panics in a way that gets all goroutine stacks printed on stderr.
|
||||
func LoudPanic(x interface{}) {
|
||||
panic(x)
|
||||
}
|
||||
64
vendor/github.com/ethereum/go-ethereum/internal/debug/trace.go
generated
vendored
Normal file
64
vendor/github.com/ethereum/go-ethereum/internal/debug/trace.go
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
// Copyright 2016 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//go:build go1.5
|
||||
// +build go1.5
|
||||
|
||||
package debug
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"runtime/trace"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
)
|
||||
|
||||
// StartGoTrace turns on tracing, writing to the given file.
|
||||
func (h *HandlerT) StartGoTrace(file string) error {
|
||||
h.mu.Lock()
|
||||
defer h.mu.Unlock()
|
||||
if h.traceW != nil {
|
||||
return errors.New("trace already in progress")
|
||||
}
|
||||
f, err := os.Create(expandHome(file))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := trace.Start(f); err != nil {
|
||||
f.Close()
|
||||
return err
|
||||
}
|
||||
h.traceW = f
|
||||
h.traceFile = file
|
||||
log.Info("Go tracing started", "dump", h.traceFile)
|
||||
return nil
|
||||
}
|
||||
|
||||
// StopTrace stops an ongoing trace.
|
||||
func (h *HandlerT) StopGoTrace() error {
|
||||
h.mu.Lock()
|
||||
defer h.mu.Unlock()
|
||||
trace.Stop()
|
||||
if h.traceW == nil {
|
||||
return errors.New("trace not in progress")
|
||||
}
|
||||
log.Info("Done writing Go trace", "dump", h.traceFile)
|
||||
h.traceW.Close()
|
||||
h.traceW = nil
|
||||
h.traceFile = ""
|
||||
return nil
|
||||
}
|
||||
32
vendor/github.com/ethereum/go-ethereum/internal/debug/trace_fallback.go
generated
vendored
Normal file
32
vendor/github.com/ethereum/go-ethereum/internal/debug/trace_fallback.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright 2016 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//go:build !go1.5
|
||||
// +build !go1.5
|
||||
|
||||
// no-op implementation of tracing methods for Go < 1.5.
|
||||
|
||||
package debug
|
||||
|
||||
import "errors"
|
||||
|
||||
func (*HandlerT) StartGoTrace(string) error {
|
||||
return errors.New("tracing is not supported on Go < 1.5")
|
||||
}
|
||||
|
||||
func (*HandlerT) StopGoTrace() error {
|
||||
return errors.New("tracing is not supported on Go < 1.5")
|
||||
}
|
||||
Reference in New Issue
Block a user