aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2019-02-28 14:38:42 -0800
committerColin Cross <ccross@android.com>2019-02-28 14:38:42 -0800
commitf7104c0ad658fb4d7824d97a2f1f2e6ec2ee888f (patch)
tree012c662c88f1e13d633346489b2f57bdd6919ea5
parent284c742a3322e1f0a02df7aefb7a3be071bbcff2 (diff)
downloadandroid_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.go30
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