github.com/sandwich-go/boost@v1.3.29/xerror/stack.go (about)

     1  package xerror
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"runtime"
     7  	"strings"
     8  )
     9  
    10  const (
    11  	// maxStackDepth marks the max stack depth for error back traces.
    12  	maxStackDepth = 32
    13  )
    14  
    15  // stack represents a stack of program counters.
    16  type stack []uintptr
    17  
    18  func callersCheckIsErrorWithStack(skip ...int) stack {
    19  	if !IsErrorWithStack {
    20  		return nil
    21  	}
    22  	return callers(skip...)
    23  }
    24  
    25  // callers returns the stack callers.
    26  func callers(skip ...int) stack {
    27  	var (
    28  		pcs [maxStackDepth]uintptr
    29  		n   = 3
    30  	)
    31  	if len(skip) > 0 {
    32  		n += skip[0]
    33  	}
    34  	return pcs[:runtime.Callers(n, pcs[:])]
    35  }
    36  
    37  // formatSubStack formats the stack for error.
    38  func formatSubStack(st stack, buffer io.StringWriter) {
    39  	index := 1
    40  	space := "  "
    41  	for _, p := range st {
    42  		if fn := runtime.FuncForPC(p - 1); fn != nil {
    43  			file, line := fn.FileLine(p - 1)
    44  			if strings.Contains(file, "<") { // like "<autogenerated>"
    45  				continue
    46  			}
    47  			if goRootForFilter != "" && len(file) >= len(goRootForFilter) && file[0:len(goRootForFilter)] == goRootForFilter { // go root
    48  				continue
    49  			}
    50  			if index > 9 {
    51  				space = " "
    52  			}
    53  			_, _ = buffer.WriteString(fmt.Sprintf("   <%d>:%s%s\n    \t%s:%d\n", index, space, fn.Name(), file, line))
    54  			index++
    55  		}
    56  	}
    57  }