54 lines
1.1 KiB
Go
54 lines
1.1 KiB
Go
package adverr
|
|
|
|
import (
|
|
"fmt"
|
|
"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]
|
|
fmt.Println(n, CallStackLength)
|
|
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()
|
|
}
|