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 }