mustHaveDWARF(t)
// External linking may bring in C symbols with unknown size. Skip.
- testenv.MustInternalLink(t, false)
+ //
+ // N.B. go build below explictly doesn't pass through
+ // -asan/-msan/-race, so we don't care about those.
+ testenv.MustInternalLink(t, testenv.NoSpecialBuildTypes)
t.Parallel()
func TestRuntimeTypeAttrInternal(t *testing.T) {
testenv.MustHaveGoBuild(t)
- testenv.MustInternalLink(t, false)
+ // N.B. go build below explictly doesn't pass through
+ // -asan/-msan/-race, so we don't care about those.
+ testenv.MustInternalLink(t, testenv.NoSpecialBuildTypes)
mustHaveDWARF(t)
func TestIssue42484(t *testing.T) {
testenv.MustHaveGoBuild(t)
- testenv.MustInternalLink(t, false) // Avoid spurious failures from external linkers.
+ // Avoid spurious failures from external linkers.
+ //
+ // N.B. go build below explictly doesn't pass through
+ // -asan/-msan/-race, so we don't care about those.
+ testenv.MustInternalLink(t, testenv.NoSpecialBuildTypes)
mustHaveDWARF(t)
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if test.mustInternalLink {
- testenv.MustInternalLink(t, test.mustHaveCGO)
+ // N.B. none of the tests pass -asan/-msan/-asan.
+ testenv.MustInternalLink(t, testenv.SpecialBuildTypes{Cgo: test.mustHaveCGO})
}
if test.mustHaveCGO {
testenv.MustHaveCGO(t)
// When external linking, symbols may be defined externally, so we allow
// undefined symbols and let external linker resolve. Skip the test.
- testenv.MustInternalLink(t, false)
+ //
+ // N.B. go build below explictly doesn't pass through
+ // -asan/-msan/-race, so we don't care about those.
+ testenv.MustInternalLink(t, testenv.NoSpecialBuildTypes)
t.Parallel()
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if test.mustInternalLink {
- testenv.MustInternalLink(t, test.mustHaveCGO)
+ testenv.MustInternalLink(t, testenv.SpecialBuildTypes{Cgo: test.mustHaveCGO})
}
if test.mustHaveCGO {
testenv.MustHaveCGO(t)
t.Parallel()
testenv.MustHaveGoBuild(t)
- testenv.MustInternalLink(t, false)
+ // N.B. the build below explictly doesn't pass through
+ // -asan/-msan/-race, so we don't care about those.
+ testenv.MustInternalLink(t, testenv.NoSpecialBuildTypes)
const source = `
package main
t.Parallel()
testenv.MustHaveGoBuild(t)
- testenv.MustInternalLink(t, false)
+ // N.B. go build below explictly doesn't pass through
+ // -asan/-msan/-race, so we don't care about those.
+ testenv.MustInternalLink(t, testenv.NoSpecialBuildTypes)
tmpdir := t.TempDir()
func TestIssue33979(t *testing.T) {
testenv.MustHaveGoBuild(t)
testenv.MustHaveCGO(t)
- testenv.MustInternalLink(t, true)
+ // N.B. go build below explictly doesn't pass through
+ // -asan/-msan/-race, so we don't care about those.
+ testenv.MustInternalLink(t, testenv.NoSpecialBuildTypes)
t.Parallel()
// This shouldn't happen with "go build". We invoke the compiler and the linker
// manually, and try to "trick" the linker with an inconsistent object file.
testenv.MustHaveGoBuild(t)
- testenv.MustInternalLink(t, false)
+ // N.B. the build below explictly doesn't pass through
+ // -asan/-msan/-race, so we don't care about those.
+ testenv.MustInternalLink(t, testenv.NoSpecialBuildTypes)
t.Parallel()
func TestInternalLinkerCgoExec(t *testing.T) {
testenv.MustHaveCGO(t)
- testenv.MustInternalLink(t, true)
+ // N.B. the go build explictly doesn't pass through
+ // -asan/-msan/-race, so we don't care about those.
+ testenv.MustInternalLink(t, testenv.SpecialBuildTypes{Cgo: true})
testGoExec(t, true, false)
}
// Test that pack-created archives can be understood by the tools.
func TestHello(t *testing.T) {
testenv.MustHaveGoBuild(t)
- testenv.MustInternalLink(t, false)
+ // N.B. the build below explictly doesn't pass through
+ // -asan/-msan/-race, so we don't care about those.
+ testenv.MustInternalLink(t, testenv.NoSpecialBuildTypes)
dir := t.TempDir()
hello := filepath.Join(dir, "hello.go")
return !platform.MustLinkExternal(runtime.GOOS, runtime.GOARCH, withCgo)
}
+// SpecialBuildTypes are interesting build types that may affect linking.
+type SpecialBuildTypes struct {
+ Cgo bool
+ Asan bool
+ Msan bool
+ Race bool
+}
+
+// NoSpecialBuildTypes indicates a standard, no cgo go build.
+var NoSpecialBuildTypes SpecialBuildTypes
+
// MustInternalLink checks that the current system can link programs with internal
// linking.
// If not, MustInternalLink calls t.Skip with an explanation.
-func MustInternalLink(t testing.TB, withCgo bool) {
- if !CanInternalLink(withCgo) {
+func MustInternalLink(t testing.TB, with SpecialBuildTypes) {
+ if with.Asan || with.Msan || with.Race {
+ t.Skipf("skipping test: internal linking with sanitizers is not supported")
+ }
+ if !CanInternalLink(with.Cgo) {
t.Helper()
- if withCgo && CanInternalLink(false) {
+ if with.Cgo && CanInternalLink(false) {
t.Skipf("skipping test: internal linking on %s/%s is not supported with cgo", runtime.GOOS, runtime.GOARCH)
}
t.Skipf("skipping test: internal linking on %s/%s is not supported", runtime.GOOS, runtime.GOARCH)
// This test runs with cgo disabled. External linking needs cgo, so
// it doesn't work if external linking is required.
- testenv.MustInternalLink(t, false)
+ //
+ // N.B. go build below explictly doesn't pass through
+ // -asan/-msan/-race, so we don't care about those.
+ testenv.MustInternalLink(t, testenv.NoSpecialBuildTypes)
if runtime.GOOS == "windows" {
t.Skipf("skipping test on %q", runtime.GOOS)
import (
"fmt"
+ "internal/asan"
"internal/goos"
- "internal/platform"
+ "internal/msan"
+ "internal/race"
"internal/testenv"
"os"
"os/exec"
default:
t.Skipf("not yet supported on %s", platform)
}
+ if asan.Enabled || msan.Enabled {
+ t.Skip("skipping test on ASAN/MSAN: triggers SIGSEGV in sanitizer runtime")
+ }
got := runTestProg(t, "testprogcgo", "CrashTraceback")
for i := 1; i <= 3; i++ {
if !strings.Contains(got, fmt.Sprintf("cgo symbolizer:%d", i)) {
- t.Errorf("missing cgo symbolizer:%d", i)
+ t.Errorf("missing cgo symbolizer:%d in %s", i, got)
}
}
}
}
testenv.MustHaveGoRun(t)
- exe, err := buildTestProg(t, "testprogcgo", buildArg)
+ var args []string
+ if buildArg != "" {
+ args = append(args, buildArg)
+ }
+ exe, err := buildTestProg(t, "testprogcgo", args...)
if err != nil {
t.Fatal(err)
}
}
func TestCgoPprofPIE(t *testing.T) {
+ if race.Enabled {
+ t.Skip("skipping test: -race + PIE not supported")
+ }
testCgoPprof(t, "-buildmode=pie", "CgoPprof", "cpuHog", "runtime.main")
}
}
func TestRaceProf(t *testing.T) {
- if !platform.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH) {
- t.Skipf("skipping on %s/%s because race detector not supported", runtime.GOOS, runtime.GOARCH)
+ if !race.Enabled {
+ t.Skip("skipping: race detector not enabled")
}
if runtime.GOOS == "windows" {
t.Skipf("skipping: test requires pthread support")
testenv.MustHaveGoRun(t)
- // This test requires building various packages with -race, so
- // it's somewhat slow.
- if testing.Short() {
- t.Skip("skipping test in -short mode")
- }
-
- exe, err := buildTestProg(t, "testprogcgo", "-race")
+ exe, err := buildTestProg(t, "testprogcgo")
if err != nil {
t.Fatal(err)
}
}
func TestRaceSignal(t *testing.T) {
- if !platform.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH) {
- t.Skipf("skipping on %s/%s because race detector not supported", runtime.GOOS, runtime.GOARCH)
+ if !race.Enabled {
+ t.Skip("skipping: race detector not enabled")
}
if runtime.GOOS == "windows" {
t.Skipf("skipping: test requires pthread support")
testenv.MustHaveGoRun(t)
- // This test requires building various packages with -race, so
- // it's somewhat slow.
- if testing.Short() {
- t.Skip("skipping test in -short mode")
- }
-
- exe, err := buildTestProg(t, "testprogcgo", "-race")
+ exe, err := buildTestProg(t, "testprogcgo")
if err != nil {
t.Fatal(err)
}
// than injecting a sigpanic.
t.Skip("no sigpanic in C on windows")
}
+ if asan.Enabled || msan.Enabled {
+ t.Skip("skipping test on ASAN/MSAN: triggers SIGSEGV in sanitizer runtime")
+ }
if runtime.GOOS == "ios" {
testenv.SkipFlaky(t, 59912)
}
case "plan9", "windows":
t.Skipf("no signals on %s", runtime.GOOS)
}
+ if asan.Enabled || msan.Enabled {
+ t.Skip("skipping test on ASAN/MSAN: triggers SIGSEGV in sanitizer runtime")
+ }
for _, test := range []string{"Segv", "SegvInCgo", "TgkillSegv", "TgkillSegvInCgo"} {
test := test
}
func TestCgoNoEscape(t *testing.T) {
+ if asan.Enabled {
+ t.Skip("skipping test: ASAN forces extra heap allocations")
+ }
got := runTestProg(t, "testprogcgo", "CgoNoEscape")
want := "OK\n"
if got != want {
}
}
-func TestDestructorCallbackRace(t *testing.T) {
- // This test requires building with -race,
- // so it's somewhat slow.
- if testing.Short() {
- t.Skip("skipping test in -short mode")
- }
-
- if !platform.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH) {
- t.Skipf("skipping on %s/%s because race detector not supported", runtime.GOOS, runtime.GOARCH)
- }
-
- t.Parallel()
-
- exe, err := buildTestProg(t, "testprogcgo", "-race")
- if err != nil {
- t.Fatal(err)
- }
-
- got, err := testenv.CleanCmdEnv(exec.Command(exe, "DestructorCallback")).CombinedOutput()
- if err != nil {
- t.Fatal(err)
- }
-
- if want := "OK\n"; string(got) != want {
- t.Errorf("expected %q, but got:\n%s", want, got)
- }
-}
-
func TestEnsureBindM(t *testing.T) {
t.Parallel()
switch runtime.GOOS {
case "windows", "plan9", "android", "ios", "openbsd": // no getcontext
t.Skipf("skipping test on %s", runtime.GOOS)
}
+ if asan.Enabled {
+ // ASAN prints this as a warning.
+ t.Skip("skipping test on ASAN because ASAN doesn't fully support makecontext/swapcontext functions")
+ }
got := runTestProg(t, "testprogcgo", "StackSwitchCallback")
skip := "SKIP\n"
if got == skip {
"errors"
"flag"
"fmt"
+ "internal/asan"
+ "internal/msan"
"internal/profile"
+ "internal/race"
"internal/testenv"
traceparse "internal/trace"
"io"
// Don't get confused if testenv.GoToolPath calls t.Skip.
target.err = errors.New("building test called t.Skip")
+ if asan.Enabled {
+ flags = append(flags, "-asan")
+ }
+ if msan.Enabled {
+ flags = append(flags, "-msan")
+ }
+ if race.Enabled {
+ flags = append(flags, "-race")
+ }
+
exe := filepath.Join(dir, name+".exe")
start := time.Now()
testCrashHandler(t, false)
}
+var deadlockBuildTypes = testenv.SpecialBuildTypes{
+ // External linking brings in cgo, causing deadlock detection not working.
+ Cgo: false,
+ Asan: asan.Enabled,
+ Msan: msan.Enabled,
+ Race: race.Enabled,
+}
+
func testDeadlock(t *testing.T, name string) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t, false)
+ testenv.MustInternalLink(t, deadlockBuildTypes)
output := runTestProg(t, "testprog", name)
want := "fatal error: all goroutines are asleep - deadlock!\n"
func TestGoexitDeadlock(t *testing.T) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t, false)
+ testenv.MustInternalLink(t, deadlockBuildTypes)
output := runTestProg(t, "testprog", "GoexitDeadlock")
want := "no goroutines (main called runtime.Goexit) - deadlock!"
func TestGoexitCrash(t *testing.T) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t, false)
+ testenv.MustInternalLink(t, deadlockBuildTypes)
output := runTestProg(t, "testprog", "GoexitExit")
want := "no goroutines (main called runtime.Goexit) - deadlock!"
func TestGoexitInPanic(t *testing.T) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t, false)
+ testenv.MustInternalLink(t, deadlockBuildTypes)
// see issue 8774: this code used to trigger an infinite recursion
output := runTestProg(t, "testprog", "GoexitInPanic")
func TestRecoveredPanicAfterGoexit(t *testing.T) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t, false)
+ testenv.MustInternalLink(t, deadlockBuildTypes)
output := runTestProg(t, "testprog", "RecoveredPanicAfterGoexit")
want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"
func TestRecoverBeforePanicAfterGoexit(t *testing.T) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t, false)
+ testenv.MustInternalLink(t, deadlockBuildTypes)
t.Parallel()
output := runTestProg(t, "testprog", "RecoverBeforePanicAfterGoexit")
func TestRecoverBeforePanicAfterGoexit2(t *testing.T) {
// External linking brings in cgo, causing deadlock detection not working.
- testenv.MustInternalLink(t, false)
+ testenv.MustInternalLink(t, deadlockBuildTypes)
t.Parallel()
output := runTestProg(t, "testprog", "RecoverBeforePanicAfterGoexit2")
if !*concurrentMapTest {
t.Skip("skipping without -run_concurrent_map_tests")
}
+ if race.Enabled {
+ t.Skip("skipping test: -race will catch the race, this test is for the built-in race detection")
+ }
testenv.MustHaveGoRun(t)
output := runTestProg(t, "testprog", "concurrentMapWrites")
want := "fatal error: concurrent map writes\n"
if !*concurrentMapTest {
t.Skip("skipping without -run_concurrent_map_tests")
}
+ if race.Enabled {
+ t.Skip("skipping test: -race will catch the race, this test is for the built-in race detection")
+ }
testenv.MustHaveGoRun(t)
output := runTestProg(t, "testprog", "concurrentMapReadWrite")
want := "fatal error: concurrent map read and map write\n"
if !*concurrentMapTest {
t.Skip("skipping without -run_concurrent_map_tests")
}
+ if race.Enabled {
+ t.Skip("skipping test: -race will catch the race, this test is for the built-in race detection")
+ }
testenv.MustHaveGoRun(t)
output := runTestProg(t, "testprog", "concurrentMapIterateWrite")
want := "fatal error: concurrent map iteration and map write\n"
func TestConcurrentMapWritesIssue69447(t *testing.T) {
testenv.MustHaveGoRun(t)
+ if race.Enabled {
+ t.Skip("skipping test: -race will catch the race, this test is for the built-in race detection")
+ }
exe, err := buildTestProg(t, "testprog")
if err != nil {
t.Fatal(err)
}
func TestBadTraceback(t *testing.T) {
+ if asan.Enabled || msan.Enabled || race.Enabled {
+ t.Skip("skipped test: checkptr mode catches the corruption")
+ }
output := runTestProg(t, "testprog", "BadTraceback")
for _, want := range []string{
"unexpected return pc",
func TestPanicOnUnsafeSlice(t *testing.T) {
output := runTestProg(t, "testprog", "panicOnNilAndEleSizeIsZero")
- want := "panic: runtime error: unsafe.Slice: ptr is nil and len is not zero"
+ // Note: This is normally a panic, but is a throw when checkptr is
+ // enabled.
+ want := "unsafe.Slice: ptr is nil and len is not zero"
if !strings.Contains(output, want) {
t.Errorf("output does not contain %q:\n%s", want, output)
}
package runtime_test
import (
- "internal/platform"
- "internal/testenv"
"os/exec"
- "runtime"
"strings"
"testing"
)
func TestExitHooks(t *testing.T) {
- bmodes := []string{""}
if testing.Short() {
t.Skip("skipping due to -short")
}
- // Note the HasCGO() test below; this is to prevent the test
- // running if CGO_ENABLED=0 is in effect.
- haverace := platform.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH)
- if haverace && testenv.HasCGO() {
- bmodes = append(bmodes, "-race")
- }
- for _, bmode := range bmodes {
- scenarios := []struct {
- mode string
- expected string
- musthave []string
- }{
- {
- mode: "simple",
- expected: "bar foo",
- },
- {
- mode: "goodexit",
- expected: "orange apple",
- },
- {
- mode: "badexit",
- expected: "blub blix",
- },
- {
- mode: "panics",
- musthave: []string{
- "fatal error: exit hook invoked panic",
- "main.testPanics",
- },
- },
- {
- mode: "callsexit",
- musthave: []string{
- "fatal error: exit hook invoked exit",
- },
+
+ scenarios := []struct {
+ mode string
+ expected string
+ musthave []string
+ }{
+ {
+ mode: "simple",
+ expected: "bar foo",
+ },
+ {
+ mode: "goodexit",
+ expected: "orange apple",
+ },
+ {
+ mode: "badexit",
+ expected: "blub blix",
+ },
+ {
+ mode: "panics",
+ musthave: []string{
+ "fatal error: exit hook invoked panic",
+ "main.testPanics",
},
- {
- mode: "exit2",
- expected: "",
+ },
+ {
+ mode: "callsexit",
+ musthave: []string{
+ "fatal error: exit hook invoked exit",
},
- }
+ },
+ {
+ mode: "exit2",
+ expected: "",
+ },
+ }
- exe, err := buildTestProg(t, "testexithooks", bmode)
- if err != nil {
- t.Fatal(err)
- }
+ exe, err := buildTestProg(t, "testexithooks")
+ if err != nil {
+ t.Fatal(err)
+ }
- bt := ""
- if bmode != "" {
- bt = " bmode: " + bmode
+ for _, s := range scenarios {
+ cmd := exec.Command(exe, []string{"-mode", s.mode}...)
+ out, _ := cmd.CombinedOutput()
+ outs := strings.ReplaceAll(string(out), "\n", " ")
+ outs = strings.TrimSpace(outs)
+ if s.expected != "" && s.expected != outs {
+ t.Fatalf("failed %s: wanted %q\noutput:\n%s",
+ s.mode, s.expected, outs)
}
- for _, s := range scenarios {
- cmd := exec.Command(exe, []string{"-mode", s.mode}...)
- out, _ := cmd.CombinedOutput()
- outs := strings.ReplaceAll(string(out), "\n", " ")
- outs = strings.TrimSpace(outs)
- if s.expected != "" && s.expected != outs {
- t.Fatalf("failed%s mode %s: wanted %q\noutput:\n%s", bt,
- s.mode, s.expected, outs)
- }
- for _, need := range s.musthave {
- if !strings.Contains(outs, need) {
- t.Fatalf("failed mode %s: output does not contain %q\noutput:\n%s",
- s.mode, need, outs)
- }
- }
- if s.expected == "" && s.musthave == nil && outs != "" {
- t.Errorf("failed mode %s: wanted no output\noutput:\n%s", s.mode, outs)
+ for _, need := range s.musthave {
+ if !strings.Contains(outs, need) {
+ t.Fatalf("failed mode %s: output does not contain %q\noutput:\n%s",
+ s.mode, need, outs)
}
}
+ if s.expected == "" && s.musthave == nil && outs != "" {
+ t.Errorf("failed mode %s: wanted no output\noutput:\n%s", s.mode, outs)
+ }
}
}
import (
"fmt"
"internal/asan"
+ "internal/msan"
+ "internal/race"
"internal/testenv"
"math/bits"
"math/rand"
}
func TestGcZombieReporting(t *testing.T) {
+ if asan.Enabled || msan.Enabled || race.Enabled {
+ t.Skip("skipped test: checkptr mode catches the issue before getting to zombie reporting")
+ }
// This test is somewhat sensitive to how the allocator works.
// Pointers in zombies slice may cross-span, thus we
// add invalidptr=0 for avoiding the badPointer check.
import (
"fmt"
+ "internal/asan"
"internal/testenv"
"reflect"
"regexp"
default:
t.Skipf("frame pointer is not supported on %s", GOARCH)
}
+ if asan.Enabled {
+ t.Skip("skipping test: ASAN forces heap allocation")
+ }
output := runTestProg(t, "testprog", "FramePointerAdjust")
if output != "" {
t.Errorf("output:\n%s\n\nwant no output", output)
register("LockOSThreadVgetrandom", LockOSThreadVgetrandom)
}
-var sinkInt int
+var sinkInt = 1
func LockOSThreadVgetrandom() {
// This is a regression test for https://go.dev/issue/73141. When that
// interesting scheduling where threads get descheduled
// in the middle of getting or putting vgetrandom
// state.
+ i := 0
for range 10 * 1000 * 1000 {
- sinkInt = 1
+ i += sinkInt
}
}()
}
// Faketime is advanced in checkdead. External linking brings in cgo,
// causing checkdead not working.
- testenv.MustInternalLink(t, false)
+ testenv.MustInternalLink(t, deadlockBuildTypes)
t.Parallel()