adverr/calltrace.go

52 lines
1.0 KiB
Go

package adverr
import (
"runtime"
"strconv"
"strings"
)
// CallTrace represents a call stack trace similar to Java's stack trace
type CallTrace struct {
frames *runtime.Frames
more bool
}
// Trace returns a new CallTrace starting from this call
// Use skip to skip the first entries in the trace
func Trace(skip int) *CallTrace {
if DisableTrace {
return nil
}
pc := make([]uintptr, CallStackLength+1)
n := runtime.Callers(skip+1, pc)
pc = pc[:n]
return &CallTrace{runtime.CallersFrames(pc), n == CallStackLength+1}
}
func (ct *CallTrace) String() string {
if ct == nil {
return ""
}
b := new(strings.Builder)
for frame, ok := ct.frames.Next(); ok; frame, ok = ct.frames.Next() {
b.WriteString("\tat ")
b.WriteString(frame.Function)
b.WriteString(" (")
b.WriteString(frame.File)
b.WriteString(":")
b.WriteString(strconv.Itoa(frame.Line))
b.WriteString(")")
b.WriteString("\n")
}
if ct.more {
b.WriteString("\t ...\n")
}
return b.String()
}