diff options
| author | Colin Cross <ccross@android.com> | 2019-02-28 14:38:42 -0800 |
|---|---|---|
| committer | Colin Cross <ccross@android.com> | 2019-02-28 14:38:42 -0800 |
| commit | f7104c0ad658fb4d7824d97a2f1f2e6ec2ee888f (patch) | |
| tree | 012c662c88f1e13d633346489b2f57bdd6919ea5 | |
| parent | 284c742a3322e1f0a02df7aefb7a3be071bbcff2 (diff) | |
| download | android_build_blueprint-f7104c0ad658fb4d7824d97a2f1f2e6ec2ee888f.tar.gz android_build_blueprint-f7104c0ad658fb4d7824d97a2f1f2e6ec2ee888f.tar.bz2 android_build_blueprint-f7104c0ad658fb4d7824d97a2f1f2e6ec2ee888f.zip | |
Support go 1.12
go 1.12 changed the stack trace of a function call during global
variable initialization to contain a function called
"PKG.init.ializers". Fix callerName to split the package path
and function name on the first "." after the last "/", and look
for functions called "init.ializers" or functions with the
prefix "init."
Change-Id: Ic2190837a8c4cde075f727bd69dd18d517a0ebc0
| -rw-r--r-- | package_ctx.go | 30 |
1 files changed, 12 insertions, 18 deletions
diff --git a/package_ctx.go b/package_ctx.go index 0c64e45..e0a03c8 100644 --- a/package_ctx.go +++ b/package_ctx.go @@ -18,6 +18,7 @@ import ( "errors" "fmt" "reflect" + "regexp" "runtime" "strings" "sync" @@ -137,12 +138,17 @@ func checkCalledFromInit() { panic("not called from an init func") } - if funcName == "init" || strings.HasPrefix(funcName, "init·") { + if funcName == "init" || strings.HasPrefix(funcName, "init·") || + funcName == "init.ializers" || strings.HasPrefix(funcName, "init.") { return } } } +// A regex to find a package path within a function name. It finds the shortest string that is +// followed by '.' and doesn't have any '/'s left. +var pkgPathRe = regexp.MustCompile(`^(.*?)\.([^/]+)$`) + // callerName returns the package path and function name of the calling // function. The skip argument has the same meaning as the skip argument of // runtime.Callers. @@ -153,25 +159,13 @@ func callerName(skip int) (pkgPath, funcName string, ok bool) { return "", "", false } - f := runtime.FuncForPC(pc[0]) - fullName := f.Name() - - lastDotIndex := strings.LastIndex(fullName, ".") - if lastDotIndex == -1 { - panic("unable to distinguish function name from package") - } - - if fullName[lastDotIndex-1] == ')' { - // The caller is a method on some type, so it's name looks like - // "pkg/path.(type).method". We need to go back one dot farther to get - // to the package name. - lastDotIndex = strings.LastIndex(fullName[:lastDotIndex], ".") + f := runtime.FuncForPC(pc[0]).Name() + s := pkgPathRe.FindStringSubmatch(f) + if len(s) < 3 { + panic(fmt.Errorf("failed to extract package path and function name from %q", f)) } - pkgPath = fullName[:lastDotIndex] - funcName = fullName[lastDotIndex+1:] - ok = true - return + return s[1], s[2], true } // pkgPathToName makes a Ninja-friendly name out of a Go package name by |
