github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/errors/stack.go (about)

     1  package errors
     2  
     3  import (
     4  	"fmt"
     5  	"runtime"
     6  )
     7  
     8  const stackTraceSize = 10
     9  
    10  // StackFrame represents a single entry in a stack trace.
    11  type StackFrame struct {
    12  	Func string
    13  	File string
    14  	Line int
    15  }
    16  
    17  // String satisfies the fmt.Stringer interface.
    18  func (f StackFrame) String() string {
    19  	return fmt.Sprintf("%s:%d - %s", f.File, f.Line, f.Func)
    20  }
    21  
    22  // Stack returns the stack trace of an error. The error must contain the stack
    23  // trace, or wrap an error that has a stack trace,
    24  func Stack(err error) []StackFrame {
    25  	if wErr, ok := err.(wrapperError); ok {
    26  		return wErr.stack
    27  	}
    28  	return nil
    29  }
    30  
    31  // getStack is a formatting wrapper around runtime.Callers. It returns a stack
    32  // trace in the form of a StackFrame slice.
    33  func getStack(skip int, size int) []StackFrame {
    34  	var (
    35  		pc    = make([]uintptr, size)
    36  		calls = runtime.Callers(skip+1, pc)
    37  		trace []StackFrame
    38  	)
    39  
    40  	for i := 0; i < calls; i++ {
    41  		f := runtime.FuncForPC(pc[i])
    42  		file, line := f.FileLine(pc[i] - 1)
    43  		trace = append(trace, StackFrame{
    44  			Func: f.Name(),
    45  			File: file,
    46  			Line: line,
    47  		})
    48  	}
    49  
    50  	return trace
    51  }