]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: add -asan option
authorFannie Zhang <fannie.zhang@arm.com>
Wed, 6 Jan 2021 08:57:44 +0000 (08:57 +0000)
committerfannie zhang <Fannie.Zhang@arm.com>
Tue, 26 Oct 2021 01:18:46 +0000 (01:18 +0000)
The -asan option compiles Go code to use the address sanitizer.  This is
intended for use when linking with C/C++ code compiled with -fsanitize=address.
When memory blocks are passed back and forth between C/C++ and Go, code in
both languages will agree as to whether the memory is validly allocated or not,
and will report errors for any use of invalid memory.

Updates #44853.

Change-Id: I0209002ef795cc1c823daae557fb80c906158db3
Reviewed-on: https://go-review.googlesource.com/c/go/+/298612
Trust: fannie zhang <Fannie.Zhang@arm.com>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
src/cmd/go/alldocs.go
src/cmd/go/go_test.go
src/cmd/go/internal/cfg/cfg.go
src/cmd/go/internal/load/pkg.go
src/cmd/go/internal/work/build.go
src/cmd/go/internal/work/exec.go
src/cmd/go/internal/work/init.go
src/cmd/go/script_test.go
src/cmd/go/testdata/script/README
src/cmd/go/testdata/script/goflags.txt
src/cmd/go/testdata/script/install_msan_and_race_require_cgo.txt

index d04ba04a533fa33ae5c572806f7eaa8a45a7c92d..817807310345dfd0c0337e5777c41809bdc852f6 100644 (file)
 //             Supported only on linux/amd64, linux/arm64
 //             and only with Clang/LLVM as the host C compiler.
 //             On linux/arm64, pie build mode will be used.
+//     -asan
+//             enable interoperation with address sanitizer.
+//             Supported only on linux/arm64, linux/amd64.
 //     -v
 //             print the names of packages as they are compiled.
 //     -work
 //             in order to keep output separate from default builds.
 //             If using the -race flag, the install suffix is automatically set to race
 //             or, if set explicitly, has _race appended to it. Likewise for the -msan
-//             flag. Using a -buildmode option that requires non-default compile flags
-//             has a similar effect.
+//             and -asan flags. Using a -buildmode option that requires non-default compile
+//             flags has a similar effect.
 //     -ldflags '[pattern=]arg list'
 //             arguments to pass on each go tool link invocation.
 //     -linkshared
index d67d01aa1e664dc92e8d97883a601b522ddfd72f..339014e94e877e798f60eaded7332d229b5b329e 100644 (file)
@@ -46,6 +46,7 @@ var (
        canRace = false // whether we can run the race detector
        canCgo  = false // whether we can use cgo
        canMSan = false // whether we can run the memory sanitizer
+       canASan = false // whether we can run the address sanitizer
 )
 
 var exeSuffix string = func() string {
@@ -197,6 +198,7 @@ func TestMain(m *testing.M) {
                testGOCACHE = strings.TrimSpace(string(out))
 
                canMSan = canCgo && sys.MSanSupported(runtime.GOOS, runtime.GOARCH)
+               canASan = canCgo && sys.ASanSupported(runtime.GOOS, runtime.GOARCH)
                canRace = canCgo && sys.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH)
                // The race detector doesn't work on Alpine Linux:
                // golang.org/issue/14481
index 37e9b2666e88bee419a275886f26257e129cc3b7..351c3ee6a508747554940aec7534c1f53a00cd8d 100644 (file)
@@ -35,6 +35,7 @@ var (
        BuildI                 bool                    // -i flag
        BuildLinkshared        bool                    // -linkshared flag
        BuildMSan              bool                    // -msan flag
+       BuildASan              bool                    // -asan flag
        BuildN                 bool                    // -n flag
        BuildO                 string                  // -o flag
        BuildP                 = runtime.GOMAXPROCS(0) // -p flag
index 99c4a9c62e339ef0b9d523539b4fcc6045ab7284..a5be48a49bc2e009d4f8c704415de532663431b2 100644 (file)
@@ -1625,6 +1625,7 @@ var cgoSyscallExclude = map[string]bool{
        "runtime/cgo":  true,
        "runtime/race": true,
        "runtime/msan": true,
+       "runtime/asan": true,
 }
 
 var foldPath = make(map[string]string)
@@ -2415,6 +2416,10 @@ func LinkerDeps(p *Package) []string {
        if cfg.BuildMSan {
                deps = append(deps, "runtime/msan")
        }
+       // Using address sanitizer forces an import of runtime/asan.
+       if cfg.BuildASan {
+               deps = append(deps, "runtime/asan")
+       }
 
        return deps
 }
index e10f647a6d323e86279e961677451fc3c715c55f..ffe33bfa4d41c428849534fd36892a676fbe6ce9 100644 (file)
@@ -75,6 +75,9 @@ and test commands:
                Supported only on linux/amd64, linux/arm64
                and only with Clang/LLVM as the host C compiler.
                On linux/arm64, pie build mode will be used.
+       -asan
+               enable interoperation with address sanitizer.
+               Supported only on linux/arm64, linux/amd64.
        -v
                print the names of packages as they are compiled.
        -work
@@ -109,8 +112,8 @@ and test commands:
                in order to keep output separate from default builds.
                If using the -race flag, the install suffix is automatically set to race
                or, if set explicitly, has _race appended to it. Likewise for the -msan
-               flag. Using a -buildmode option that requires non-default compile flags
-               has a similar effect.
+               and -asan flags. Using a -buildmode option that requires non-default compile
+               flags has a similar effect.
        -ldflags '[pattern=]arg list'
                arguments to pass on each go tool link invocation.
        -linkshared
@@ -309,6 +312,7 @@ func AddBuildFlags(cmd *base.Command, mask BuildFlagMask) {
        cmd.Flag.StringVar(&cfg.BuildPkgdir, "pkgdir", "", "")
        cmd.Flag.BoolVar(&cfg.BuildRace, "race", false, "")
        cmd.Flag.BoolVar(&cfg.BuildMSan, "msan", false, "")
+       cmd.Flag.BoolVar(&cfg.BuildASan, "asan", false, "")
        cmd.Flag.Var((*tagsFlag)(&cfg.BuildContext.BuildTags), "tags", "")
        cmd.Flag.Var((*base.StringsFlag)(&cfg.BuildToolexec), "toolexec", "")
        cmd.Flag.BoolVar(&cfg.BuildTrimpath, "trimpath", false, "")
index d4e24d4cd13b2a9dbfecfc6a1bf5d3fd0ee49bd7..62d814382881afbca28960b2818faae3fbdbd896 100644 (file)
@@ -2736,6 +2736,10 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo
                cgoCFLAGS = append([]string{"-fsanitize=memory"}, cgoCFLAGS...)
                cgoLDFLAGS = append([]string{"-fsanitize=memory"}, cgoLDFLAGS...)
        }
+       if cfg.BuildASan {
+               cgoCFLAGS = append([]string{"-fsanitize=address"}, cgoCFLAGS...)
+               cgoLDFLAGS = append([]string{"-fsanitize=address"}, cgoLDFLAGS...)
+       }
 
        // Allows including _cgo_export.h, as well as the user's .h files,
        // from .[ch] files in the package.
@@ -2757,7 +2761,7 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo
        if p.Standard && p.ImportPath == "runtime/cgo" {
                cgoflags = append(cgoflags, "-import_runtime_cgo=false")
        }
-       if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/msan" || p.ImportPath == "runtime/cgo") {
+       if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/msan" || p.ImportPath == "runtime/cgo" || p.ImportPath == "runtime/asan") {
                cgoflags = append(cgoflags, "-import_syscall=false")
        }
 
index 6a29abb03b87b77439ea3b1abff2105bec984b86..56e39f8c52a071510e3cb057ae1cbbb5d1f3f9c5 100644 (file)
@@ -87,7 +87,7 @@ func fuzzInstrumentFlags() []string {
 }
 
 func instrumentInit() {
-       if !cfg.BuildRace && !cfg.BuildMSan {
+       if !cfg.BuildRace && !cfg.BuildMSan && !cfg.BuildASan {
                return
        }
        if cfg.BuildRace && cfg.BuildMSan {
@@ -95,17 +95,30 @@ func instrumentInit() {
                base.SetExitStatus(2)
                base.Exit()
        }
+       if cfg.BuildRace && cfg.BuildASan {
+               fmt.Fprintf(os.Stderr, "go: may not use -race and -asan simultaneously\n")
+               base.SetExitStatus(2)
+               base.Exit()
+       }
+       if cfg.BuildMSan && cfg.BuildASan {
+               fmt.Fprintf(os.Stderr, "go: may not use -msan and -asan simultaneously\n")
+               base.SetExitStatus(2)
+               base.Exit()
+       }
        if cfg.BuildMSan && !sys.MSanSupported(cfg.Goos, cfg.Goarch) {
                fmt.Fprintf(os.Stderr, "-msan is not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
                base.SetExitStatus(2)
                base.Exit()
        }
-       if cfg.BuildRace {
-               if !sys.RaceDetectorSupported(cfg.Goos, cfg.Goarch) {
-                       fmt.Fprintf(os.Stderr, "go: -race is only supported on linux/amd64, linux/ppc64le, linux/arm64, freebsd/amd64, netbsd/amd64, darwin/amd64, darwin/arm64, and windows/amd64\n")
-                       base.SetExitStatus(2)
-                       base.Exit()
-               }
+       if cfg.BuildRace && !sys.RaceDetectorSupported(cfg.Goos, cfg.Goarch) {
+               fmt.Fprintf(os.Stderr, "-race is not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
+               base.SetExitStatus(2)
+               base.Exit()
+       }
+       if cfg.BuildASan && !sys.ASanSupported(cfg.Goos, cfg.Goarch) {
+               fmt.Fprintf(os.Stderr, "-asan is not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
+               base.SetExitStatus(2)
+               base.Exit()
        }
        mode := "race"
        if cfg.BuildMSan {
@@ -116,6 +129,9 @@ func instrumentInit() {
                        cfg.BuildBuildmode = "pie"
                }
        }
+       if cfg.BuildASan {
+               mode = "asan"
+       }
        modeFlag := "-" + mode
 
        if !cfg.BuildContext.CgoEnabled {
index ac9764db949423e32a8adcc2412dbb256f44ba78..acb1f91b440a97d58c67615f73cd6a091e2e721a 100644 (file)
@@ -353,6 +353,8 @@ Script:
                                ok = canCgo
                        case "msan":
                                ok = canMSan
+                       case "asan":
+                               ok = canASan
                        case "race":
                                ok = canRace
                        case "net":
index 48e4055b0bdb971397be7dd2b0b909205a46a588..2b88e880c9369375ec86a9b53ff2358e23da0c92 100644 (file)
@@ -79,7 +79,7 @@ should only run when the condition is satisfied. The available conditions are:
  - Compiler names, like [gccgo], [gc].
  - Test environment details:
    - [short] for testing.Short()
-   - [cgo], [msan], [race] for whether cgo, msan, and the race detector can be used
+   - [cgo], [msan], [asan], [race] for whether cgo, msan, asan, and the race detector can be used
    - [net] for whether the external network can be used
    - [link] for testenv.HasLink()
    - [root] for os.Geteuid() == 0
index 686d1138b8318e3d0ed5affd6673ee66ead24c96..f4872ffd356b5b3874e1205c0959c20c79a38ca0 100644 (file)
@@ -9,7 +9,7 @@ stdout '[\\/]runtime$'
 
 env GOFLAGS=-race OLDGOARCH=$GOARCH OLDGOOS=$GOOS GOARCH=386 GOOS=linux
 ! go list runtime
-stderr 'race is only supported on'
+stderr 'race is not supported on linux/386'
 
 env GOARCH=$OLDGOARCH GOOS=$OLDGOOS
 
index 7985cd2ab2728dfbb7311e6e96069b62f4b86792..5e88f7b8dbdc7288c3bdc6d8f7c4774b7e7fa1a0 100644 (file)
@@ -1,7 +1,5 @@
 # Tests Issue #21895
 
-[!msan] [!race] skip 'skipping because both msan and the race detector are not supported'
-
 env CGO_ENABLED=0
 
 [race] ! go install -race triv.go
@@ -12,6 +10,10 @@ env CGO_ENABLED=0
 [msan] stderr '-msan requires cgo'
 [msan] ! stderr '-race'
 
+[asan] ! go install -asan triv.go
+[asan] stderr '-asan requires cgo'
+[asan] ! stderr '-msan'
+
 -- triv.go --
 package main