go.undefinedlabs.com/scopeagent@v0.4.2/instrumentation/util.go (about) 1 package instrumentation 2 3 import ( 4 "fmt" 5 "path" 6 "runtime" 7 "strings" 8 9 "go.undefinedlabs.com/scopeagent/ast" 10 ) 11 12 func GetPackageAndName(pc uintptr) (string, string) { 13 return splitPackageAndName(runtime.FuncForPC(pc).Name()) 14 } 15 16 func splitPackageAndName(funcFullName string) (string, string) { 17 lastSlash := strings.LastIndexByte(funcFullName, '/') 18 if lastSlash < 0 { 19 lastSlash = 0 20 } 21 firstDot := strings.IndexByte(funcFullName[lastSlash:], '.') + lastSlash 22 packName := funcFullName[:firstDot] 23 // If the package has the format: _/{path...} 24 // We convert the path from absolute to relative to the source root 25 sourceRoot := GetSourceRoot() 26 if len(packName) > 0 && packName[0] == '_' && strings.Index(packName, sourceRoot) != -1 { 27 packName = strings.Replace(packName, path.Dir(sourceRoot)+"/", "", -1)[1:] 28 } 29 funcName := funcFullName[firstDot+1:] 30 return packName, funcName 31 } 32 33 func GetPackageAndNameAndBoundaries(pc uintptr) (string, string, string) { 34 pName, fName := GetPackageAndName(pc) 35 36 isInstanceFunc := false 37 if len(fName) > 0 { 38 pf := strings.Index(fName, ")") 39 if fName[0] == '(' && pf != -1 && pf+1 < len(fName) && fName[pf+1] == '.' { 40 isInstanceFunc = true 41 } 42 } 43 44 if !isInstanceFunc { 45 dotIndex := strings.IndexByte(fName, '.') 46 if dotIndex != -1 { 47 fName = fName[:dotIndex] 48 } 49 } 50 51 fBoundaries := "" 52 sourceBounds, err := ast.GetFuncSourceForName(pc, fName) 53 if err != nil { 54 Logger().Printf("error calculating the source boundaries for '%s': %v", fName, err) 55 } 56 if sourceBounds != nil { 57 fBoundaries = fmt.Sprintf("%s:%d:%d", sourceBounds.File, sourceBounds.Start.Line, sourceBounds.End.Line) 58 } 59 return pName, fName, fBoundaries 60 }