mirror of
https://github.com/fleetdm/fleet
synced 2026-05-06 06:48:54 +00:00
45 lines
859 B
Go
45 lines
859 B
Go
|
|
package ctxerr
|
||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
"path/filepath"
|
||
|
|
"runtime"
|
||
|
|
)
|
||
|
|
|
||
|
|
const (
|
||
|
|
maxDepth = 10 // maximum number of stack frames to record
|
||
|
|
)
|
||
|
|
|
||
|
|
type stackTracer interface {
|
||
|
|
List() []string
|
||
|
|
}
|
||
|
|
|
||
|
|
// stack holds a snapshot of program counters.
|
||
|
|
type stack []uintptr
|
||
|
|
|
||
|
|
// newStack captures a stack trace. skip specifies the number of frames to skip from
|
||
|
|
// a stack trace. skip=0 records stack.New call as the innermost frame.
|
||
|
|
func newStack(skip int) stack {
|
||
|
|
pc := make([]uintptr, maxDepth+1)
|
||
|
|
pc = pc[:runtime.Callers(skip+2, pc)]
|
||
|
|
return stack(pc)
|
||
|
|
}
|
||
|
|
|
||
|
|
// List collects stack traces formatted as strings.
|
||
|
|
func (s stack) List() []string {
|
||
|
|
var lines []string
|
||
|
|
|
||
|
|
cf := runtime.CallersFrames(s)
|
||
|
|
for {
|
||
|
|
f, more := cf.Next()
|
||
|
|
line := fmt.Sprintf("%s (%s:%d)", f.Function, filepath.Base(f.File), f.Line)
|
||
|
|
lines = append(lines, line)
|
||
|
|
|
||
|
|
if !more {
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return lines
|
||
|
|
}
|