distribution/vendor/github.com/anacrolix/log/callers.go

64 lines
1.2 KiB
Go

package log
import (
"runtime"
"runtime/debug"
"strings"
"sync"
)
func getSingleCallerPc(skip int) uintptr {
var pc [1]uintptr
runtime.Callers(skip+2, pc[:])
return pc[0]
}
type Loc struct {
Package string
Function string
File string
Line int
}
// This is the package returned for a caller frame that is in the main package for a binary.
const mainPackageFrameImport = "main"
// Reads the build info to get the true full import path for the main package.
var mainPackagePath = sync.OnceValue(func() string {
info, ok := debug.ReadBuildInfo()
if ok {
return info.Path
}
return mainPackageFrameImport
})
func locFromPc(pc uintptr) Loc {
f, _ := runtime.CallersFrames([]uintptr{pc}).Next()
lastSlash := strings.LastIndexByte(f.Function, '/')
firstDot := strings.IndexByte(f.Function[lastSlash+1:], '.')
pkg := f.Function[:lastSlash+1+firstDot]
if pkg == mainPackageFrameImport {
pkg = mainPackagePath()
}
return Loc{
Package: pkg,
Function: f.Function,
File: f.File,
Line: f.Line,
}
}
var pcToLoc sync.Map
func getMsgLogLoc(msg Msg) Loc {
var pc [1]uintptr
msg.Callers(1, pc[:])
locIf, ok := pcToLoc.Load(pc[0])
if ok {
return locIf.(Loc)
}
loc := locFromPc(pc[0])
pcToLoc.Store(pc[0], loc)
return loc
}