• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 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
5//go:build linux || (freebsd && amd64)
6
7package sanitizers_test
8
9import (
10	"fmt"
11	"internal/platform"
12	"internal/testenv"
13	"os"
14	"strings"
15	"testing"
16)
17
18func TestShared(t *testing.T) {
19	testenv.MustHaveGoBuild(t)
20	testenv.MustHaveCGO(t)
21	testenv.MustHaveBuildMode(t, "c-shared")
22
23	t.Parallel()
24	requireOvercommit(t)
25
26	GOOS, err := goEnv("GOOS")
27	if err != nil {
28		t.Fatal(err)
29	}
30
31	GOARCH, err := goEnv("GOARCH")
32	if err != nil {
33		t.Fatal(err)
34	}
35
36	libExt := "so"
37	if GOOS == "darwin" {
38		libExt = "dylib"
39	}
40
41	cases := []struct {
42		src       string
43		sanitizer string
44	}{
45		{
46			src:       "msan_shared.go",
47			sanitizer: "memory",
48		},
49		{
50			src:       "tsan_shared.go",
51			sanitizer: "thread",
52		},
53	}
54
55	for _, tc := range cases {
56		tc := tc
57		name := strings.TrimSuffix(tc.src, ".go")
58		//The memory sanitizer tests require support for the -msan option.
59		if tc.sanitizer == "memory" && !platform.MSanSupported(GOOS, GOARCH) {
60			t.Logf("skipping %s test on %s/%s; -msan option is not supported.", name, GOOS, GOARCH)
61			continue
62		}
63		if tc.sanitizer == "thread" && !compilerRequiredTsanVersion(GOOS, GOARCH) {
64			t.Logf("skipping %s test on %s/%s; compiler version too old for -tsan.", name, GOOS, GOARCH)
65			continue
66		}
67
68		t.Run(name, func(t *testing.T) {
69			t.Parallel()
70			config := configure(tc.sanitizer)
71			config.skipIfCSanitizerBroken(t)
72
73			dir := newTempDir(t)
74			defer dir.RemoveAll(t)
75
76			lib := dir.Join(fmt.Sprintf("lib%s.%s", name, libExt))
77			mustRun(t, config.goCmd("build", "-buildmode=c-shared", "-o", lib, srcPath(tc.src)))
78
79			cSrc := dir.Join("main.c")
80			if err := os.WriteFile(cSrc, cMain, 0600); err != nil {
81				t.Fatalf("failed to write C source file: %v", err)
82			}
83
84			dstBin := dir.Join(name)
85			cmd, err := cc(config.cFlags...)
86			if err != nil {
87				t.Fatal(err)
88			}
89			cmd.Args = append(cmd.Args, config.ldFlags...)
90			cmd.Args = append(cmd.Args, "-o", dstBin, cSrc, lib)
91			mustRun(t, cmd)
92
93			cmd = hangProneCmd(dstBin)
94			replaceEnv(cmd, "LD_LIBRARY_PATH", ".")
95			mustRun(t, cmd)
96		})
97	}
98}
99