mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-08-01 23:30:10 +00:00
TUN-6724: Migrate to sentry-go from raven-go
This commit is contained in:
76
vendor/github.com/getsentry/raven-go/stacktrace.go
generated
vendored
76
vendor/github.com/getsentry/raven-go/stacktrace.go
generated
vendored
@@ -61,14 +61,17 @@ func GetOrNewStacktrace(err error, skip int, context int, appPackagePrefixes []s
|
||||
for _, f := range stacktracer.StackTrace() {
|
||||
pc := uintptr(f) - 1
|
||||
fn := runtime.FuncForPC(pc)
|
||||
var fName string
|
||||
var file string
|
||||
var line int
|
||||
if fn != nil {
|
||||
file, line = fn.FileLine(pc)
|
||||
fName = fn.Name()
|
||||
} else {
|
||||
file = "unknown"
|
||||
fName = "unknown"
|
||||
}
|
||||
frame := NewStacktraceFrame(pc, file, line, context, appPackagePrefixes)
|
||||
frame := NewStacktraceFrame(pc, fName, file, line, context, appPackagePrefixes)
|
||||
if frame != nil {
|
||||
frames = append([]*StacktraceFrame{frame}, frames...)
|
||||
}
|
||||
@@ -89,14 +92,27 @@ func GetOrNewStacktrace(err error, skip int, context int, appPackagePrefixes []s
|
||||
// be considered "in app".
|
||||
func NewStacktrace(skip int, context int, appPackagePrefixes []string) *Stacktrace {
|
||||
var frames []*StacktraceFrame
|
||||
for i := 1 + skip; ; i++ {
|
||||
pc, file, line, ok := runtime.Caller(i)
|
||||
if !ok {
|
||||
break
|
||||
|
||||
callerPcs := make([]uintptr, 100)
|
||||
numCallers := runtime.Callers(skip+2, callerPcs)
|
||||
|
||||
// If there are no callers, the entire stacktrace is nil
|
||||
if numCallers == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
callersFrames := runtime.CallersFrames(callerPcs)
|
||||
|
||||
for {
|
||||
fr, more := callersFrames.Next()
|
||||
if fr.Func != nil {
|
||||
frame := NewStacktraceFrame(fr.PC, fr.Function, fr.File, fr.Line, context, appPackagePrefixes)
|
||||
if frame != nil {
|
||||
frames = append(frames, frame)
|
||||
}
|
||||
}
|
||||
frame := NewStacktraceFrame(pc, file, line, context, appPackagePrefixes)
|
||||
if frame != nil {
|
||||
frames = append(frames, frame)
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
}
|
||||
// If there are no frames, the entire stacktrace is nil
|
||||
@@ -122,9 +138,9 @@ func NewStacktrace(skip int, context int, appPackagePrefixes []string) *Stacktra
|
||||
//
|
||||
// appPackagePrefixes is a list of prefixes used to check whether a package should
|
||||
// be considered "in app".
|
||||
func NewStacktraceFrame(pc uintptr, file string, line, context int, appPackagePrefixes []string) *StacktraceFrame {
|
||||
func NewStacktraceFrame(pc uintptr, fName, file string, line, context int, appPackagePrefixes []string) *StacktraceFrame {
|
||||
frame := &StacktraceFrame{AbsolutePath: file, Filename: trimPath(file), Lineno: line, InApp: false}
|
||||
frame.Module, frame.Function = functionName(pc)
|
||||
frame.Module, frame.Function = functionName(fName)
|
||||
|
||||
// `runtime.goexit` is effectively a placeholder that comes from
|
||||
// runtime/asm_amd64.s and is meaningless.
|
||||
@@ -143,7 +159,7 @@ func NewStacktraceFrame(pc uintptr, file string, line, context int, appPackagePr
|
||||
}
|
||||
|
||||
if context > 0 {
|
||||
contextLines, lineIdx := fileContext(file, line, context)
|
||||
contextLines, lineIdx := sourceCodeLoader.Load(file, line, context)
|
||||
if len(contextLines) > 0 {
|
||||
for i, line := range contextLines {
|
||||
switch {
|
||||
@@ -157,7 +173,7 @@ func NewStacktraceFrame(pc uintptr, file string, line, context int, appPackagePr
|
||||
}
|
||||
}
|
||||
} else if context == -1 {
|
||||
contextLine, _ := fileContext(file, line, 0)
|
||||
contextLine, _ := sourceCodeLoader.Load(file, line, 0)
|
||||
if len(contextLine) > 0 {
|
||||
frame.ContextLine = string(contextLine[0])
|
||||
}
|
||||
@@ -166,12 +182,8 @@ func NewStacktraceFrame(pc uintptr, file string, line, context int, appPackagePr
|
||||
}
|
||||
|
||||
// Retrieve the name of the package and function containing the PC.
|
||||
func functionName(pc uintptr) (pack string, name string) {
|
||||
fn := runtime.FuncForPC(pc)
|
||||
if fn == nil {
|
||||
return
|
||||
}
|
||||
name = fn.Name()
|
||||
func functionName(fName string) (pack string, name string) {
|
||||
name = fName
|
||||
// We get this:
|
||||
// runtime/debug.*T·ptrmethod
|
||||
// and want this:
|
||||
@@ -185,24 +197,36 @@ func functionName(pc uintptr) (pack string, name string) {
|
||||
return
|
||||
}
|
||||
|
||||
var fileCacheLock sync.Mutex
|
||||
var fileCache = make(map[string][][]byte)
|
||||
type SourceCodeLoader interface {
|
||||
Load(filename string, line, context int) ([][]byte, int)
|
||||
}
|
||||
|
||||
func fileContext(filename string, line, context int) ([][]byte, int) {
|
||||
fileCacheLock.Lock()
|
||||
defer fileCacheLock.Unlock()
|
||||
lines, ok := fileCache[filename]
|
||||
var sourceCodeLoader SourceCodeLoader = &fsLoader{cache: make(map[string][][]byte)}
|
||||
|
||||
func SetSourceCodeLoader(loader SourceCodeLoader) {
|
||||
sourceCodeLoader = loader
|
||||
}
|
||||
|
||||
type fsLoader struct {
|
||||
mu sync.Mutex
|
||||
cache map[string][][]byte
|
||||
}
|
||||
|
||||
func (fs *fsLoader) Load(filename string, line, context int) ([][]byte, int) {
|
||||
fs.mu.Lock()
|
||||
defer fs.mu.Unlock()
|
||||
lines, ok := fs.cache[filename]
|
||||
if !ok {
|
||||
data, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
// cache errors as nil slice: code below handles it correctly
|
||||
// otherwise when missing the source or running as a different user, we try
|
||||
// reading the file on each error which is unnecessary
|
||||
fileCache[filename] = nil
|
||||
fs.cache[filename] = nil
|
||||
return nil, 0
|
||||
}
|
||||
lines = bytes.Split(data, []byte{'\n'})
|
||||
fileCache[filename] = lines
|
||||
fs.cache[filename] = lines
|
||||
}
|
||||
|
||||
if lines == nil {
|
||||
|
Reference in New Issue
Block a user