github.com/panjjo/go@v0.0.0-20161104043856-d62b31386338/src/runtime/crash_cgo_test.go (about)

     1  // Copyright 2012 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  // +build cgo
     6  
     7  package runtime_test
     8  
     9  import (
    10  	"bytes"
    11  	"fmt"
    12  	"internal/testenv"
    13  	"os"
    14  	"os/exec"
    15  	"runtime"
    16  	"strings"
    17  	"testing"
    18  	"time"
    19  )
    20  
    21  func TestCgoCrashHandler(t *testing.T) {
    22  	testCrashHandler(t, true)
    23  }
    24  
    25  func TestCgoSignalDeadlock(t *testing.T) {
    26  	if testing.Short() && runtime.GOOS == "windows" {
    27  		t.Skip("Skipping in short mode") // takes up to 64 seconds
    28  	}
    29  	got := runTestProg(t, "testprogcgo", "CgoSignalDeadlock")
    30  	want := "OK\n"
    31  	if got != want {
    32  		t.Fatalf("expected %q, but got:\n%s", want, got)
    33  	}
    34  }
    35  
    36  func TestCgoTraceback(t *testing.T) {
    37  	got := runTestProg(t, "testprogcgo", "CgoTraceback")
    38  	want := "OK\n"
    39  	if got != want {
    40  		t.Fatalf("expected %q, but got:\n%s", want, got)
    41  	}
    42  }
    43  
    44  func TestCgoCallbackGC(t *testing.T) {
    45  	switch runtime.GOOS {
    46  	case "plan9", "windows":
    47  		t.Skipf("no pthreads on %s", runtime.GOOS)
    48  	case "freebsd":
    49  		testenv.SkipFlaky(t, 16396)
    50  	}
    51  	if testing.Short() {
    52  		switch {
    53  		case runtime.GOOS == "dragonfly":
    54  			t.Skip("see golang.org/issue/11990")
    55  		case runtime.GOOS == "linux" && runtime.GOARCH == "arm":
    56  			t.Skip("too slow for arm builders")
    57  		case runtime.GOOS == "linux" && (runtime.GOARCH == "mips64" || runtime.GOARCH == "mips64le"):
    58  			t.Skip("too slow for mips64x builders")
    59  		}
    60  	}
    61  	got := runTestProg(t, "testprogcgo", "CgoCallbackGC")
    62  	want := "OK\n"
    63  	if got != want {
    64  		t.Fatalf("expected %q, but got:\n%s", want, got)
    65  	}
    66  }
    67  
    68  func TestCgoExternalThreadPanic(t *testing.T) {
    69  	if runtime.GOOS == "plan9" {
    70  		t.Skipf("no pthreads on %s", runtime.GOOS)
    71  	}
    72  	got := runTestProg(t, "testprogcgo", "CgoExternalThreadPanic")
    73  	want := "panic: BOOM"
    74  	if !strings.Contains(got, want) {
    75  		t.Fatalf("want failure containing %q. output:\n%s\n", want, got)
    76  	}
    77  }
    78  
    79  func TestCgoExternalThreadSIGPROF(t *testing.T) {
    80  	// issue 9456.
    81  	switch runtime.GOOS {
    82  	case "plan9", "windows":
    83  		t.Skipf("no pthreads on %s", runtime.GOOS)
    84  	case "darwin":
    85  		if runtime.GOARCH != "arm" && runtime.GOARCH != "arm64" {
    86  			// static constructor needs external linking, but we don't support
    87  			// external linking on OS X 10.6.
    88  			out, err := exec.Command("uname", "-r").Output()
    89  			if err != nil {
    90  				t.Fatalf("uname -r failed: %v", err)
    91  			}
    92  			// OS X 10.6 == Darwin 10.x
    93  			if strings.HasPrefix(string(out), "10.") {
    94  				t.Skipf("no external linking on OS X 10.6")
    95  			}
    96  		}
    97  	}
    98  	if runtime.GOARCH == "ppc64" {
    99  		// TODO(austin) External linking not implemented on
   100  		// ppc64 (issue #8912)
   101  		t.Skipf("no external linking on ppc64")
   102  	}
   103  
   104  	exe, err := buildTestProg(t, "testprogcgo", "-tags=threadprof")
   105  	if err != nil {
   106  		t.Fatal(err)
   107  	}
   108  
   109  	got, err := testEnv(exec.Command(exe, "CgoExternalThreadSIGPROF")).CombinedOutput()
   110  	if err != nil {
   111  		t.Fatalf("exit status: %v\n%s", err, got)
   112  	}
   113  
   114  	if want := "OK\n"; string(got) != want {
   115  		t.Fatalf("expected %q, but got:\n%s", want, got)
   116  	}
   117  }
   118  
   119  func TestCgoExternalThreadSignal(t *testing.T) {
   120  	// issue 10139
   121  	switch runtime.GOOS {
   122  	case "plan9", "windows":
   123  		t.Skipf("no pthreads on %s", runtime.GOOS)
   124  	}
   125  
   126  	exe, err := buildTestProg(t, "testprogcgo", "-tags=threadprof")
   127  	if err != nil {
   128  		t.Fatal(err)
   129  	}
   130  
   131  	got, err := testEnv(exec.Command(exe, "CgoExternalThreadSIGPROF")).CombinedOutput()
   132  	if err != nil {
   133  		t.Fatalf("exit status: %v\n%s", err, got)
   134  	}
   135  
   136  	want := []byte("OK\n")
   137  	if !bytes.Equal(got, want) {
   138  		t.Fatalf("expected %q, but got:\n%s", want, got)
   139  	}
   140  }
   141  
   142  func TestCgoDLLImports(t *testing.T) {
   143  	// test issue 9356
   144  	if runtime.GOOS != "windows" {
   145  		t.Skip("skipping windows specific test")
   146  	}
   147  	got := runTestProg(t, "testprogcgo", "CgoDLLImportsMain")
   148  	want := "OK\n"
   149  	if got != want {
   150  		t.Fatalf("expected %q, but got %v", want, got)
   151  	}
   152  }
   153  
   154  func TestCgoExecSignalMask(t *testing.T) {
   155  	// Test issue 13164.
   156  	switch runtime.GOOS {
   157  	case "windows", "plan9":
   158  		t.Skipf("skipping signal mask test on %s", runtime.GOOS)
   159  	}
   160  	got := runTestProg(t, "testprogcgo", "CgoExecSignalMask")
   161  	want := "OK\n"
   162  	if got != want {
   163  		t.Errorf("expected %q, got %v", want, got)
   164  	}
   165  }
   166  
   167  func TestEnsureDropM(t *testing.T) {
   168  	// Test for issue 13881.
   169  	switch runtime.GOOS {
   170  	case "windows", "plan9":
   171  		t.Skipf("skipping dropm test on %s", runtime.GOOS)
   172  	}
   173  	got := runTestProg(t, "testprogcgo", "EnsureDropM")
   174  	want := "OK\n"
   175  	if got != want {
   176  		t.Errorf("expected %q, got %v", want, got)
   177  	}
   178  }
   179  
   180  // Test for issue 14387.
   181  // Test that the program that doesn't need any cgo pointer checking
   182  // takes about the same amount of time with it as without it.
   183  func TestCgoCheckBytes(t *testing.T) {
   184  	// Make sure we don't count the build time as part of the run time.
   185  	testenv.MustHaveGoBuild(t)
   186  	exe, err := buildTestProg(t, "testprogcgo")
   187  	if err != nil {
   188  		t.Fatal(err)
   189  	}
   190  
   191  	// Try it 10 times to avoid flakiness.
   192  	const tries = 10
   193  	var tot1, tot2 time.Duration
   194  	for i := 0; i < tries; i++ {
   195  		cmd := testEnv(exec.Command(exe, "CgoCheckBytes"))
   196  		cmd.Env = append(cmd.Env, "GODEBUG=cgocheck=0", fmt.Sprintf("GO_CGOCHECKBYTES_TRY=%d", i))
   197  
   198  		start := time.Now()
   199  		cmd.Run()
   200  		d1 := time.Since(start)
   201  
   202  		cmd = testEnv(exec.Command(exe, "CgoCheckBytes"))
   203  		cmd.Env = append(cmd.Env, fmt.Sprintf("GO_CGOCHECKBYTES_TRY=%d", i))
   204  
   205  		start = time.Now()
   206  		cmd.Run()
   207  		d2 := time.Since(start)
   208  
   209  		if d1*20 > d2 {
   210  			// The slow version (d2) was less than 20 times
   211  			// slower than the fast version (d1), so OK.
   212  			return
   213  		}
   214  
   215  		tot1 += d1
   216  		tot2 += d2
   217  	}
   218  
   219  	t.Errorf("cgo check too slow: got %v, expected at most %v", tot2/tries, (tot1/tries)*20)
   220  }
   221  
   222  func TestCgoPanicDeadlock(t *testing.T) {
   223  	// test issue 14432
   224  	got := runTestProg(t, "testprogcgo", "CgoPanicDeadlock")
   225  	want := "panic: cgo error\n\n"
   226  	if !strings.HasPrefix(got, want) {
   227  		t.Fatalf("output does not start with %q:\n%s", want, got)
   228  	}
   229  }
   230  
   231  func TestCgoCCodeSIGPROF(t *testing.T) {
   232  	got := runTestProg(t, "testprogcgo", "CgoCCodeSIGPROF")
   233  	want := "OK\n"
   234  	if got != want {
   235  		t.Errorf("expected %q got %v", want, got)
   236  	}
   237  }
   238  
   239  func TestCgoCrashTraceback(t *testing.T) {
   240  	if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
   241  		t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH)
   242  	}
   243  	got := runTestProg(t, "testprogcgo", "CrashTraceback")
   244  	for i := 1; i <= 3; i++ {
   245  		if !strings.Contains(got, fmt.Sprintf("cgo symbolizer:%d", i)) {
   246  			t.Errorf("missing cgo symbolizer:%d", i)
   247  		}
   248  	}
   249  }
   250  
   251  func TestCgoTracebackContext(t *testing.T) {
   252  	got := runTestProg(t, "testprogcgo", "TracebackContext")
   253  	want := "OK\n"
   254  	if got != want {
   255  		t.Errorf("expected %q got %v", want, got)
   256  	}
   257  }
   258  
   259  func testCgoPprof(t *testing.T, buildArg, runArg string) {
   260  	if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
   261  		t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH)
   262  	}
   263  	testenv.MustHaveGoRun(t)
   264  
   265  	exe, err := buildTestProg(t, "testprogcgo", buildArg)
   266  	if err != nil {
   267  		t.Fatal(err)
   268  	}
   269  
   270  	got, err := testEnv(exec.Command(exe, runArg)).CombinedOutput()
   271  	if err != nil {
   272  		t.Fatal(err)
   273  	}
   274  	fn := strings.TrimSpace(string(got))
   275  	defer os.Remove(fn)
   276  
   277  	cmd := testEnv(exec.Command(testenv.GoToolPath(t), "tool", "pprof", "-top", "-nodecount=1", exe, fn))
   278  
   279  	found := false
   280  	for i, e := range cmd.Env {
   281  		if strings.HasPrefix(e, "PPROF_TMPDIR=") {
   282  			cmd.Env[i] = "PPROF_TMPDIR=" + os.TempDir()
   283  			found = true
   284  			break
   285  		}
   286  	}
   287  	if !found {
   288  		cmd.Env = append(cmd.Env, "PPROF_TMPDIR="+os.TempDir())
   289  	}
   290  
   291  	top, err := cmd.CombinedOutput()
   292  	t.Logf("%s", top)
   293  	if err != nil {
   294  		t.Fatal(err)
   295  	}
   296  
   297  	if !bytes.Contains(top, []byte("cpuHog")) {
   298  		t.Error("missing cpuHog in pprof output")
   299  	}
   300  }
   301  
   302  func TestCgoPprof(t *testing.T) {
   303  	testCgoPprof(t, "", "CgoPprof")
   304  }
   305  
   306  func TestCgoPprofPIE(t *testing.T) {
   307  	testCgoPprof(t, "-ldflags=-extldflags=-pie", "CgoPprof")
   308  }
   309  
   310  func TestCgoPprofThread(t *testing.T) {
   311  	testCgoPprof(t, "", "CgoPprofThread")
   312  }
   313  
   314  func TestCgoPprofThreadNoTraceback(t *testing.T) {
   315  	testCgoPprof(t, "", "CgoPprofThreadNoTraceback")
   316  }
   317  
   318  func TestRaceProf(t *testing.T) {
   319  	if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
   320  		t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH)
   321  	}
   322  
   323  	testenv.MustHaveGoRun(t)
   324  
   325  	// This test requires building various packages with -race, so
   326  	// it's somewhat slow.
   327  	if testing.Short() {
   328  		t.Skip("skipping test in -short mode")
   329  	}
   330  
   331  	exe, err := buildTestProg(t, "testprogcgo", "-race")
   332  	if err != nil {
   333  		t.Fatal(err)
   334  	}
   335  
   336  	got, err := testEnv(exec.Command(exe, "CgoRaceprof")).CombinedOutput()
   337  	if err != nil {
   338  		t.Fatal(err)
   339  	}
   340  	want := "OK\n"
   341  	if string(got) != want {
   342  		t.Errorf("expected %q got %s", want, got)
   343  	}
   344  }
   345  
   346  func TestRaceSignal(t *testing.T) {
   347  	if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
   348  		t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH)
   349  	}
   350  
   351  	testenv.MustHaveGoRun(t)
   352  
   353  	// This test requires building various packages with -race, so
   354  	// it's somewhat slow.
   355  	if testing.Short() {
   356  		t.Skip("skipping test in -short mode")
   357  	}
   358  
   359  	exe, err := buildTestProg(t, "testprogcgo", "-race")
   360  	if err != nil {
   361  		t.Fatal(err)
   362  	}
   363  
   364  	got, err := testEnv(exec.Command(exe, "CgoRaceSignal")).CombinedOutput()
   365  	if err != nil {
   366  		t.Logf("%s\n", got)
   367  		t.Fatal(err)
   368  	}
   369  	want := "OK\n"
   370  	if string(got) != want {
   371  		t.Errorf("expected %q got %s", want, got)
   372  	}
   373  }