runtime: scan register backing store on ia64
[official-gcc.git] / libgo / go / runtime / crash_cgo_test.go
blob35321470425a79cf91d707c6aff920883c3a718f
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.
5 // +build cgo
7 package runtime_test
9 import (
10 "bytes"
11 "fmt"
12 "internal/testenv"
13 "os"
14 "os/exec"
15 "runtime"
16 "strconv"
17 "strings"
18 "testing"
19 "time"
22 func TestCgoCrashHandler(t *testing.T) {
23 t.Parallel()
24 testCrashHandler(t, true)
27 func TestCgoSignalDeadlock(t *testing.T) {
28 // Don't call t.Parallel, since too much work going on at the
29 // same time can cause the testprogcgo code to overrun its
30 // timeouts (issue #18598).
32 if testing.Short() && runtime.GOOS == "windows" {
33 t.Skip("Skipping in short mode") // takes up to 64 seconds
35 got := runTestProg(t, "testprogcgo", "CgoSignalDeadlock")
36 want := "OK\n"
37 if got != want {
38 t.Fatalf("expected %q, but got:\n%s", want, got)
42 func TestCgoTraceback(t *testing.T) {
43 t.Parallel()
44 got := runTestProg(t, "testprogcgo", "CgoTraceback")
45 want := "OK\n"
46 if got != want {
47 t.Fatalf("expected %q, but got:\n%s", want, got)
51 func TestCgoCallbackGC(t *testing.T) {
52 t.Parallel()
53 switch runtime.GOOS {
54 case "plan9", "windows":
55 t.Skipf("no pthreads on %s", runtime.GOOS)
57 if testing.Short() {
58 switch {
59 case runtime.GOOS == "dragonfly":
60 t.Skip("see golang.org/issue/11990")
61 case runtime.GOOS == "linux" && runtime.GOARCH == "arm":
62 t.Skip("too slow for arm builders")
63 case runtime.GOOS == "linux" && (runtime.GOARCH == "mips64" || runtime.GOARCH == "mips64le"):
64 t.Skip("too slow for mips64x builders")
67 got := runTestProg(t, "testprogcgo", "CgoCallbackGC")
68 want := "OK\n"
69 if got != want {
70 t.Fatalf("expected %q, but got:\n%s", want, got)
74 func TestCgoExternalThreadPanic(t *testing.T) {
75 t.Parallel()
76 if runtime.GOOS == "plan9" {
77 t.Skipf("no pthreads on %s", runtime.GOOS)
79 got := runTestProg(t, "testprogcgo", "CgoExternalThreadPanic")
80 want := "panic: BOOM"
81 if !strings.Contains(got, want) {
82 t.Fatalf("want failure containing %q. output:\n%s\n", want, got)
86 func TestCgoExternalThreadSIGPROF(t *testing.T) {
87 t.Parallel()
88 // issue 9456.
89 switch runtime.GOOS {
90 case "plan9", "windows":
91 t.Skipf("no pthreads on %s", runtime.GOOS)
92 case "darwin":
93 if runtime.GOARCH != "arm" && runtime.GOARCH != "arm64" {
94 // static constructor needs external linking, but we don't support
95 // external linking on OS X 10.6.
96 out, err := exec.Command("uname", "-r").Output()
97 if err != nil {
98 t.Fatalf("uname -r failed: %v", err)
100 // OS X 10.6 == Darwin 10.x
101 if strings.HasPrefix(string(out), "10.") {
102 t.Skipf("no external linking on OS X 10.6")
106 if runtime.GOARCH == "ppc64" {
107 // TODO(austin) External linking not implemented on
108 // ppc64 (issue #8912)
109 t.Skipf("no external linking on ppc64")
112 exe, err := buildTestProg(t, "testprogcgo", "-tags=threadprof")
113 if err != nil {
114 t.Fatal(err)
117 got, err := testenv.CleanCmdEnv(exec.Command(exe, "CgoExternalThreadSIGPROF")).CombinedOutput()
118 if err != nil {
119 t.Fatalf("exit status: %v\n%s", err, got)
122 if want := "OK\n"; string(got) != want {
123 t.Fatalf("expected %q, but got:\n%s", want, got)
127 func TestCgoExternalThreadSignal(t *testing.T) {
128 t.Parallel()
129 // issue 10139
130 switch runtime.GOOS {
131 case "plan9", "windows":
132 t.Skipf("no pthreads on %s", runtime.GOOS)
135 exe, err := buildTestProg(t, "testprogcgo", "-tags=threadprof")
136 if err != nil {
137 t.Fatal(err)
140 got, err := testenv.CleanCmdEnv(exec.Command(exe, "CgoExternalThreadSIGPROF")).CombinedOutput()
141 if err != nil {
142 t.Fatalf("exit status: %v\n%s", err, got)
145 want := []byte("OK\n")
146 if !bytes.Equal(got, want) {
147 t.Fatalf("expected %q, but got:\n%s", want, got)
151 func TestCgoDLLImports(t *testing.T) {
152 // test issue 9356
153 if runtime.GOOS != "windows" {
154 t.Skip("skipping windows specific test")
156 got := runTestProg(t, "testprogcgo", "CgoDLLImportsMain")
157 want := "OK\n"
158 if got != want {
159 t.Fatalf("expected %q, but got %v", want, got)
163 func TestCgoExecSignalMask(t *testing.T) {
164 t.Parallel()
165 // Test issue 13164.
166 switch runtime.GOOS {
167 case "windows", "plan9":
168 t.Skipf("skipping signal mask test on %s", runtime.GOOS)
170 got := runTestProg(t, "testprogcgo", "CgoExecSignalMask")
171 want := "OK\n"
172 if got != want {
173 t.Errorf("expected %q, got %v", want, got)
177 func TestEnsureDropM(t *testing.T) {
178 t.Parallel()
179 // Test for issue 13881.
180 switch runtime.GOOS {
181 case "windows", "plan9":
182 t.Skipf("skipping dropm test on %s", runtime.GOOS)
184 got := runTestProg(t, "testprogcgo", "EnsureDropM")
185 want := "OK\n"
186 if got != want {
187 t.Errorf("expected %q, got %v", want, got)
191 // Test for issue 14387.
192 // Test that the program that doesn't need any cgo pointer checking
193 // takes about the same amount of time with it as without it.
194 func TestCgoCheckBytes(t *testing.T) {
195 t.Parallel()
196 // Make sure we don't count the build time as part of the run time.
197 testenv.MustHaveGoBuild(t)
198 exe, err := buildTestProg(t, "testprogcgo")
199 if err != nil {
200 t.Fatal(err)
203 // Try it 10 times to avoid flakiness.
204 const tries = 10
205 var tot1, tot2 time.Duration
206 for i := 0; i < tries; i++ {
207 cmd := testenv.CleanCmdEnv(exec.Command(exe, "CgoCheckBytes"))
208 cmd.Env = append(cmd.Env, "GODEBUG=cgocheck=0", fmt.Sprintf("GO_CGOCHECKBYTES_TRY=%d", i))
210 start := time.Now()
211 cmd.Run()
212 d1 := time.Since(start)
214 cmd = testenv.CleanCmdEnv(exec.Command(exe, "CgoCheckBytes"))
215 cmd.Env = append(cmd.Env, fmt.Sprintf("GO_CGOCHECKBYTES_TRY=%d", i))
217 start = time.Now()
218 cmd.Run()
219 d2 := time.Since(start)
221 if d1*20 > d2 {
222 // The slow version (d2) was less than 20 times
223 // slower than the fast version (d1), so OK.
224 return
227 tot1 += d1
228 tot2 += d2
231 t.Errorf("cgo check too slow: got %v, expected at most %v", tot2/tries, (tot1/tries)*20)
234 func TestCgoPanicDeadlock(t *testing.T) {
235 t.Parallel()
236 // test issue 14432
237 got := runTestProg(t, "testprogcgo", "CgoPanicDeadlock")
238 want := "panic: cgo error\n\n"
239 if !strings.HasPrefix(got, want) {
240 t.Fatalf("output does not start with %q:\n%s", want, got)
244 func TestCgoCCodeSIGPROF(t *testing.T) {
245 t.Parallel()
246 got := runTestProg(t, "testprogcgo", "CgoCCodeSIGPROF")
247 want := "OK\n"
248 if got != want {
249 t.Errorf("expected %q got %v", want, got)
253 func TestCgoCrashTraceback(t *testing.T) {
254 t.Parallel()
255 if runtime.GOOS != "linux" || (runtime.GOARCH != "amd64" && runtime.GOARCH != "ppc64le") {
256 t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH)
258 if runtime.Compiler == "gccgo" {
259 t.Skip("gccgo does not have SetCgoTraceback")
261 got := runTestProg(t, "testprogcgo", "CrashTraceback")
262 for i := 1; i <= 3; i++ {
263 if !strings.Contains(got, fmt.Sprintf("cgo symbolizer:%d", i)) {
264 t.Errorf("missing cgo symbolizer:%d", i)
269 func TestCgoTracebackContext(t *testing.T) {
270 t.Parallel()
271 if runtime.Compiler == "gccgo" {
272 t.Skip("gccgo does not have SetCgoTraceback")
274 got := runTestProg(t, "testprogcgo", "TracebackContext")
275 want := "OK\n"
276 if got != want {
277 t.Errorf("expected %q got %v", want, got)
281 func testCgoPprof(t *testing.T, buildArg, runArg string) {
282 t.Parallel()
283 if runtime.GOOS != "linux" || (runtime.GOARCH != "amd64" && runtime.GOARCH != "ppc64le") {
284 t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH)
286 if runtime.Compiler == "gccgo" {
287 t.Skip("gccgo does not have SetCgoTraceback")
289 testenv.MustHaveGoRun(t)
291 exe, err := buildTestProg(t, "testprogcgo", buildArg)
292 if err != nil {
293 t.Fatal(err)
296 got, err := testenv.CleanCmdEnv(exec.Command(exe, runArg)).CombinedOutput()
297 if err != nil {
298 if testenv.Builder() == "linux-amd64-alpine" {
299 // See Issue 18243 and Issue 19938.
300 t.Skipf("Skipping failing test on Alpine (golang.org/issue/18243). Ignoring error: %v", err)
302 t.Fatal(err)
304 fn := strings.TrimSpace(string(got))
305 defer os.Remove(fn)
307 for try := 0; try < 2; try++ {
308 cmd := testenv.CleanCmdEnv(exec.Command(testenv.GoToolPath(t), "tool", "pprof", "-top", "-nodecount=1"))
309 // Check that pprof works both with and without explicit executable on command line.
310 if try == 0 {
311 cmd.Args = append(cmd.Args, exe, fn)
312 } else {
313 cmd.Args = append(cmd.Args, fn)
316 found := false
317 for i, e := range cmd.Env {
318 if strings.HasPrefix(e, "PPROF_TMPDIR=") {
319 cmd.Env[i] = "PPROF_TMPDIR=" + os.TempDir()
320 found = true
321 break
324 if !found {
325 cmd.Env = append(cmd.Env, "PPROF_TMPDIR="+os.TempDir())
328 top, err := cmd.CombinedOutput()
329 t.Logf("%s:\n%s", cmd.Args, top)
330 if err != nil {
331 t.Error(err)
332 } else if !bytes.Contains(top, []byte("cpuHog")) {
333 t.Error("missing cpuHog in pprof output")
338 func TestCgoPprof(t *testing.T) {
339 testCgoPprof(t, "", "CgoPprof")
342 func TestCgoPprofPIE(t *testing.T) {
343 testCgoPprof(t, "-buildmode=pie", "CgoPprof")
346 func TestCgoPprofThread(t *testing.T) {
347 testCgoPprof(t, "", "CgoPprofThread")
350 func TestCgoPprofThreadNoTraceback(t *testing.T) {
351 testCgoPprof(t, "", "CgoPprofThreadNoTraceback")
354 func TestRaceProf(t *testing.T) {
355 if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
356 t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH)
358 if runtime.Compiler == "gccgo" {
359 t.Skip("gccgo does not have SetCgoTraceback")
362 testenv.MustHaveGoRun(t)
364 // This test requires building various packages with -race, so
365 // it's somewhat slow.
366 if testing.Short() {
367 t.Skip("skipping test in -short mode")
370 exe, err := buildTestProg(t, "testprogcgo", "-race")
371 if err != nil {
372 t.Fatal(err)
375 got, err := testenv.CleanCmdEnv(exec.Command(exe, "CgoRaceprof")).CombinedOutput()
376 if err != nil {
377 t.Fatal(err)
379 want := "OK\n"
380 if string(got) != want {
381 t.Errorf("expected %q got %s", want, got)
385 func TestRaceSignal(t *testing.T) {
386 t.Parallel()
387 if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
388 t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH)
391 testenv.MustHaveGoRun(t)
393 // This test requires building various packages with -race, so
394 // it's somewhat slow.
395 if testing.Short() {
396 t.Skip("skipping test in -short mode")
399 exe, err := buildTestProg(t, "testprogcgo", "-race")
400 if err != nil {
401 t.Fatal(err)
404 got, err := testenv.CleanCmdEnv(exec.Command(exe, "CgoRaceSignal")).CombinedOutput()
405 if err != nil {
406 t.Logf("%s\n", got)
407 t.Fatal(err)
409 want := "OK\n"
410 if string(got) != want {
411 t.Errorf("expected %q got %s", want, got)
415 func TestCgoNumGoroutine(t *testing.T) {
416 switch runtime.GOOS {
417 case "windows", "plan9":
418 t.Skipf("skipping numgoroutine test on %s", runtime.GOOS)
420 t.Parallel()
421 got := runTestProg(t, "testprogcgo", "NumGoroutine")
422 want := "OK\n"
423 if got != want {
424 t.Errorf("expected %q got %v", want, got)
428 func TestCatchPanic(t *testing.T) {
429 t.Parallel()
430 switch runtime.GOOS {
431 case "plan9", "windows":
432 t.Skipf("no signals on %s", runtime.GOOS)
433 case "darwin":
434 if runtime.GOARCH == "amd64" {
435 t.Skipf("crash() on darwin/amd64 doesn't raise SIGABRT")
439 testenv.MustHaveGoRun(t)
441 exe, err := buildTestProg(t, "testprogcgo")
442 if err != nil {
443 t.Fatal(err)
446 for _, early := range []bool{true, false} {
447 cmd := testenv.CleanCmdEnv(exec.Command(exe, "CgoCatchPanic"))
448 // Make sure a panic results in a crash.
449 cmd.Env = append(cmd.Env, "GOTRACEBACK=crash")
450 if early {
451 // Tell testprogcgo to install an early signal handler for SIGABRT
452 cmd.Env = append(cmd.Env, "CGOCATCHPANIC_EARLY_HANDLER=1")
454 if out, err := cmd.CombinedOutput(); err != nil {
455 t.Errorf("testprogcgo CgoCatchPanic failed: %v\n%s", err, out)
460 func TestCgoLockOSThreadExit(t *testing.T) {
461 switch runtime.GOOS {
462 case "plan9", "windows":
463 t.Skipf("no pthreads on %s", runtime.GOOS)
465 t.Parallel()
466 testLockOSThreadExit(t, "testprogcgo")
469 func TestWindowsStackMemoryCgo(t *testing.T) {
470 if runtime.GOOS != "windows" {
471 t.Skip("skipping windows specific test")
473 testenv.SkipFlaky(t, 22575)
474 o := runTestProg(t, "testprogcgo", "StackMemory")
475 stackUsage, err := strconv.Atoi(o)
476 if err != nil {
477 t.Fatalf("Failed to read stack usage: %v", err)
479 if expected, got := 100<<10, stackUsage; got > expected {
480 t.Fatalf("expected < %d bytes of memory per thread, got %d", expected, got)
484 func TestSigStackSwapping(t *testing.T) {
485 switch runtime.GOOS {
486 case "plan9", "windows":
487 t.Skipf("no sigaltstack on %s", runtime.GOOS)
489 t.Parallel()
490 got := runTestProg(t, "testprogcgo", "SigStack")
491 want := "OK\n"
492 if got != want {
493 t.Errorf("expected %q got %v", want, got)