asan_test.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // Copyright 2021 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package sanitizers_test
  5. import (
  6. "strings"
  7. "testing"
  8. )
  9. func TestASAN(t *testing.T) {
  10. goos, err := goEnv("GOOS")
  11. if err != nil {
  12. t.Fatal(err)
  13. }
  14. goarch, err := goEnv("GOARCH")
  15. if err != nil {
  16. t.Fatal(err)
  17. }
  18. // The asan tests require support for the -asan option.
  19. if !aSanSupported(goos, goarch) {
  20. t.Skipf("skipping on %s/%s; -asan option is not supported.", goos, goarch)
  21. }
  22. t.Parallel()
  23. requireOvercommit(t)
  24. config := configure("address")
  25. config.skipIfCSanitizerBroken(t)
  26. mustRun(t, config.goCmd("build", "std"))
  27. cases := []struct {
  28. src string
  29. memoryAccessError string
  30. errorLocation string
  31. }{
  32. {src: "asan1_fail.go", memoryAccessError: "heap-use-after-free", errorLocation: "asan1_fail.go:25"},
  33. {src: "asan2_fail.go", memoryAccessError: "heap-buffer-overflow", errorLocation: "asan2_fail.go:31"},
  34. {src: "asan3_fail.go", memoryAccessError: "use-after-poison", errorLocation: "asan3_fail.go:13"},
  35. {src: "asan4_fail.go", memoryAccessError: "use-after-poison", errorLocation: "asan4_fail.go:13"},
  36. {src: "asan5_fail.go", memoryAccessError: "use-after-poison", errorLocation: "asan5_fail.go:18"},
  37. {src: "asan_useAfterReturn.go"},
  38. }
  39. for _, tc := range cases {
  40. tc := tc
  41. name := strings.TrimSuffix(tc.src, ".go")
  42. t.Run(name, func(t *testing.T) {
  43. t.Parallel()
  44. dir := newTempDir(t)
  45. defer dir.RemoveAll(t)
  46. outPath := dir.Join(name)
  47. mustRun(t, config.goCmd("build", "-o", outPath, srcPath(tc.src)))
  48. cmd := hangProneCmd(outPath)
  49. if tc.memoryAccessError != "" {
  50. outb, err := cmd.CombinedOutput()
  51. out := string(outb)
  52. if err != nil && strings.Contains(out, tc.memoryAccessError) {
  53. // This string is output if the
  54. // sanitizer library needs a
  55. // symbolizer program and can't find it.
  56. const noSymbolizer = "external symbolizer"
  57. // Check if -asan option can correctly print where the error occurred.
  58. if tc.errorLocation != "" &&
  59. !strings.Contains(out, tc.errorLocation) &&
  60. !strings.Contains(out, noSymbolizer) &&
  61. compilerSupportsLocation() {
  62. t.Errorf("%#q exited without expected location of the error\n%s; got failure\n%s", strings.Join(cmd.Args, " "), tc.errorLocation, out)
  63. }
  64. return
  65. }
  66. t.Fatalf("%#q exited without expected memory access error\n%s; got failure\n%s", strings.Join(cmd.Args, " "), tc.memoryAccessError, out)
  67. }
  68. mustRun(t, cmd)
  69. })
  70. }
  71. }