123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- package xreflect
- import (
- "fmt"
- "io"
- "runtime"
- "strings"
- )
- type Frame struct {
-
-
- Function string
-
-
-
-
- File string
- Line int
- }
- func (f Frame) String() string {
-
-
-
-
-
-
- var sb strings.Builder
- sb.WriteString(f.Function)
- if len(f.File) > 0 {
- if sb.Len() > 0 {
- sb.WriteRune(' ')
- }
- fmt.Fprintf(&sb, "(%v", f.File)
- if f.Line > 0 {
- fmt.Fprintf(&sb, ":%d", f.Line)
- }
- sb.WriteRune(')')
- }
- if sb.Len() == 0 {
- return "unknown"
- }
- return sb.String()
- }
- const _defaultCallersDepth = 8
- type Stack []Frame
- func (fs Stack) String() string {
- items := make([]string, len(fs))
- for i, f := range fs {
- items[i] = f.String()
- }
- return strings.Join(items, "; ")
- }
- func (fs Stack) Format(w fmt.State, c rune) {
- if !w.Flag('+') {
-
- io.WriteString(w, fs.String())
- return
- }
- for _, f := range fs {
- fmt.Fprintln(w, f.Function)
- fmt.Fprintf(w, "\t%v:%v\n", f.File, f.Line)
- }
- }
- func (fs Stack) CallerName() string {
- for _, f := range fs {
- if shouldIgnoreFrame(f) {
- continue
- }
- return f.Function
- }
- return "n/a"
- }
- func CallerStack(skip, depth int) Stack {
- if depth <= 0 {
- depth = _defaultCallersDepth
- }
- pcs := make([]uintptr, depth)
-
- n := runtime.Callers(skip+2, pcs)
- pcs = pcs[:n]
- result := make([]Frame, 0, n)
- frames := runtime.CallersFrames(pcs)
- for f, more := frames.Next(); more; f, more = frames.Next() {
- result = append(result, Frame{
- Function: sanitize(f.Function),
- File: f.File,
- Line: f.Line,
- })
- }
- return result
- }
|