1
2
3
4
5
6
7 package sanitizers_test
8
9 import (
10 "internal/testenv"
11 "strings"
12 "testing"
13 )
14
15 func TestTSAN(t *testing.T) {
16 testenv.MustHaveGoBuild(t)
17 testenv.MustHaveCGO(t)
18
19 goos, err := goEnv("GOOS")
20 if err != nil {
21 t.Fatal(err)
22 }
23 goarch, err := goEnv("GOARCH")
24 if err != nil {
25 t.Fatal(err)
26 }
27
28 if !compilerRequiredTsanVersion(goos, goarch) {
29 t.Skipf("skipping on %s/%s; compiler version for -tsan option is too old.", goos, goarch)
30 }
31
32 t.Parallel()
33 requireOvercommit(t)
34 config := configure("thread")
35 config.skipIfCSanitizerBroken(t)
36
37 mustRun(t, config.goCmd("build", "std"))
38
39 cases := []struct {
40 src string
41 needsRuntime bool
42 }{
43 {src: "tsan.go"},
44 {src: "tsan2.go"},
45 {src: "tsan3.go"},
46 {src: "tsan4.go"},
47 {src: "tsan5.go", needsRuntime: true},
48 {src: "tsan6.go", needsRuntime: true},
49 {src: "tsan7.go", needsRuntime: true},
50 {src: "tsan8.go"},
51 {src: "tsan9.go"},
52 {src: "tsan10.go", needsRuntime: true},
53 {src: "tsan11.go", needsRuntime: true},
54 {src: "tsan12.go", needsRuntime: true},
55 {src: "tsan13.go", needsRuntime: true},
56 {src: "tsan14.go", needsRuntime: true},
57 {src: "tsan15.go", needsRuntime: true},
58 }
59 for _, tc := range cases {
60 tc := tc
61 name := strings.TrimSuffix(tc.src, ".go")
62 t.Run(name, func(t *testing.T) {
63 t.Parallel()
64
65 dir := newTempDir(t)
66 defer dir.RemoveAll(t)
67
68 outPath := dir.Join(name)
69 mustRun(t, config.goCmd("build", "-o", outPath, srcPath(tc.src)))
70
71 cmd := hangProneCmd(outPath)
72 if tc.needsRuntime {
73 config.skipIfRuntimeIncompatible(t)
74 }
75
76
77 cmd.Env = append(cmd.Environ(), "TSAN_OPTIONS=halt_on_error=1")
78 mustRun(t, cmd)
79 })
80 }
81 }
82
View as plain text