1// +build windows
2
3package runtime_test
4
5import (
6	"internal/testenv"
7	"io/ioutil"
8	"os"
9	"os/exec"
10	"path/filepath"
11	"runtime"
12	"strings"
13	"testing"
14)
15
16func TestVectoredHandlerDontCrashOnLibrary(t *testing.T) {
17	if *flagQuick {
18		t.Skip("-quick")
19	}
20	if runtime.GOARCH != "amd64" {
21		t.Skip("this test can only run on windows/amd64")
22	}
23	testenv.MustHaveGoBuild(t)
24	testenv.MustHaveExecPath(t, "gcc")
25	testprog.Lock()
26	defer testprog.Unlock()
27	dir, err := ioutil.TempDir("", "go-build")
28	if err != nil {
29		t.Fatalf("failed to create temp directory: %v", err)
30	}
31	defer os.RemoveAll(dir)
32
33	// build go dll
34	dll := filepath.Join(dir, "testwinlib.dll")
35	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dll, "--buildmode", "c-shared", "testdata/testwinlib/main.go")
36	out, err := testenv.CleanCmdEnv(cmd).CombinedOutput()
37	if err != nil {
38		t.Fatalf("failed to build go library: %s\n%s", err, out)
39	}
40
41	// build c program
42	exe := filepath.Join(dir, "test.exe")
43	cmd = exec.Command("gcc", "-L"+dir, "-I"+dir, "-ltestwinlib", "-o", exe, "testdata/testwinlib/main.c")
44	out, err = testenv.CleanCmdEnv(cmd).CombinedOutput()
45	if err != nil {
46		t.Fatalf("failed to build c exe: %s\n%s", err, out)
47	}
48
49	// run test program
50	cmd = exec.Command(exe)
51	out, err = testenv.CleanCmdEnv(cmd).CombinedOutput()
52	if err != nil {
53		t.Fatalf("failure while running executable: %s\n%s", err, out)
54	}
55	expectedOutput := "exceptionCount: 1\ncontinueCount: 1\n"
56	// cleaning output
57	cleanedOut := strings.ReplaceAll(string(out), "\r\n", "\n")
58	if cleanedOut != expectedOutput {
59		t.Errorf("expected output %q, got %q", expectedOutput, cleanedOut)
60	}
61}
62