github.com/mtsmfm/go/src@v0.0.0-20221020090648-44bdcb9f8fde/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 //go:build cgo 6 7 package runtime_test 8 9 import ( 10 "fmt" 11 "internal/goos" 12 "internal/testenv" 13 "os" 14 "os/exec" 15 "runtime" 16 "strconv" 17 "strings" 18 "testing" 19 "time" 20 ) 21 22 func TestCgoCrashHandler(t *testing.T) { 23 t.Parallel() 24 testCrashHandler(t, true) 25 } 26 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). 31 32 if testing.Short() && runtime.GOOS == "windows" { 33 t.Skip("Skipping in short mode") // takes up to 64 seconds 34 } 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) 39 } 40 } 41 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) 48 } 49 } 50 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) 56 } 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") 65 } 66 } 67 if testenv.Builder() == "darwin-amd64-10_14" { 68 // TODO(#23011): When the 10.14 builders are gone, remove this skip. 69 t.Skip("skipping due to platform bug on macOS 10.14; see https://golang.org/issue/43926") 70 } 71 got := runTestProg(t, "testprogcgo", "CgoCallbackGC") 72 want := "OK\n" 73 if got != want { 74 t.Fatalf("expected %q, but got:\n%s", want, got) 75 } 76 } 77 78 func TestCgoExternalThreadPanic(t *testing.T) { 79 t.Parallel() 80 if runtime.GOOS == "plan9" { 81 t.Skipf("no pthreads on %s", runtime.GOOS) 82 } 83 got := runTestProg(t, "testprogcgo", "CgoExternalThreadPanic") 84 want := "panic: BOOM" 85 if !strings.Contains(got, want) { 86 t.Fatalf("want failure containing %q. output:\n%s\n", want, got) 87 } 88 } 89 90 func TestCgoExternalThreadSIGPROF(t *testing.T) { 91 t.Parallel() 92 // issue 9456. 93 switch runtime.GOOS { 94 case "plan9", "windows": 95 t.Skipf("no pthreads on %s", runtime.GOOS) 96 } 97 98 got := runTestProg(t, "testprogcgo", "CgoExternalThreadSIGPROF", "GO_START_SIGPROF_THREAD=1") 99 if want := "OK\n"; got != want { 100 t.Fatalf("expected %q, but got:\n%s", want, got) 101 } 102 } 103 104 func TestCgoExternalThreadSignal(t *testing.T) { 105 t.Parallel() 106 // issue 10139 107 switch runtime.GOOS { 108 case "plan9", "windows": 109 t.Skipf("no pthreads on %s", runtime.GOOS) 110 } 111 112 got := runTestProg(t, "testprogcgo", "CgoExternalThreadSignal") 113 if want := "OK\n"; got != want { 114 t.Fatalf("expected %q, but got:\n%s", want, got) 115 } 116 } 117 118 func TestCgoDLLImports(t *testing.T) { 119 // test issue 9356 120 if runtime.GOOS != "windows" { 121 t.Skip("skipping windows specific test") 122 } 123 got := runTestProg(t, "testprogcgo", "CgoDLLImportsMain") 124 want := "OK\n" 125 if got != want { 126 t.Fatalf("expected %q, but got %v", want, got) 127 } 128 } 129 130 func TestCgoExecSignalMask(t *testing.T) { 131 t.Parallel() 132 // Test issue 13164. 133 switch runtime.GOOS { 134 case "windows", "plan9": 135 t.Skipf("skipping signal mask test on %s", runtime.GOOS) 136 } 137 got := runTestProg(t, "testprogcgo", "CgoExecSignalMask", "GOTRACEBACK=system") 138 want := "OK\n" 139 if got != want { 140 t.Errorf("expected %q, got %v", want, got) 141 } 142 } 143 144 func TestEnsureDropM(t *testing.T) { 145 t.Parallel() 146 // Test for issue 13881. 147 switch runtime.GOOS { 148 case "windows", "plan9": 149 t.Skipf("skipping dropm test on %s", runtime.GOOS) 150 } 151 got := runTestProg(t, "testprogcgo", "EnsureDropM") 152 want := "OK\n" 153 if got != want { 154 t.Errorf("expected %q, got %v", want, got) 155 } 156 } 157 158 // Test for issue 14387. 159 // Test that the program that doesn't need any cgo pointer checking 160 // takes about the same amount of time with it as without it. 161 func TestCgoCheckBytes(t *testing.T) { 162 t.Parallel() 163 // Make sure we don't count the build time as part of the run time. 164 testenv.MustHaveGoBuild(t) 165 exe, err := buildTestProg(t, "testprogcgo") 166 if err != nil { 167 t.Fatal(err) 168 } 169 170 // Try it 10 times to avoid flakiness. 171 const tries = 10 172 var tot1, tot2 time.Duration 173 for i := 0; i < tries; i++ { 174 cmd := testenv.CleanCmdEnv(exec.Command(exe, "CgoCheckBytes")) 175 cmd.Env = append(cmd.Env, "GODEBUG=cgocheck=0", fmt.Sprintf("GO_CGOCHECKBYTES_TRY=%d", i)) 176 177 start := time.Now() 178 cmd.Run() 179 d1 := time.Since(start) 180 181 cmd = testenv.CleanCmdEnv(exec.Command(exe, "CgoCheckBytes")) 182 cmd.Env = append(cmd.Env, fmt.Sprintf("GO_CGOCHECKBYTES_TRY=%d", i)) 183 184 start = time.Now() 185 cmd.Run() 186 d2 := time.Since(start) 187 188 if d1*20 > d2 { 189 // The slow version (d2) was less than 20 times 190 // slower than the fast version (d1), so OK. 191 return 192 } 193 194 tot1 += d1 195 tot2 += d2 196 } 197 198 t.Errorf("cgo check too slow: got %v, expected at most %v", tot2/tries, (tot1/tries)*20) 199 } 200 201 func TestCgoPanicDeadlock(t *testing.T) { 202 t.Parallel() 203 // test issue 14432 204 got := runTestProg(t, "testprogcgo", "CgoPanicDeadlock") 205 want := "panic: cgo error\n\n" 206 if !strings.HasPrefix(got, want) { 207 t.Fatalf("output does not start with %q:\n%s", want, got) 208 } 209 } 210 211 func TestCgoCCodeSIGPROF(t *testing.T) { 212 t.Parallel() 213 got := runTestProg(t, "testprogcgo", "CgoCCodeSIGPROF") 214 want := "OK\n" 215 if got != want { 216 t.Errorf("expected %q got %v", want, got) 217 } 218 } 219 220 func TestCgoPprofCallback(t *testing.T) { 221 t.Parallel() 222 switch runtime.GOOS { 223 case "windows", "plan9": 224 t.Skipf("skipping cgo pprof callback test on %s", runtime.GOOS) 225 } 226 got := runTestProg(t, "testprogcgo", "CgoPprofCallback") 227 want := "OK\n" 228 if got != want { 229 t.Errorf("expected %q got %v", want, got) 230 } 231 } 232 233 func TestCgoCrashTraceback(t *testing.T) { 234 t.Parallel() 235 switch platform := runtime.GOOS + "/" + runtime.GOARCH; platform { 236 case "darwin/amd64": 237 case "linux/amd64": 238 case "linux/arm64": 239 case "linux/ppc64le": 240 default: 241 t.Skipf("not yet supported on %s", platform) 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 TestCgoCrashTracebackGo(t *testing.T) { 252 t.Parallel() 253 switch platform := runtime.GOOS + "/" + runtime.GOARCH; platform { 254 case "darwin/amd64": 255 case "linux/amd64": 256 case "linux/arm64": 257 case "linux/ppc64le": 258 default: 259 t.Skipf("not yet supported on %s", platform) 260 } 261 got := runTestProg(t, "testprogcgo", "CrashTracebackGo") 262 for i := 1; i <= 3; i++ { 263 want := fmt.Sprintf("main.h%d", i) 264 if !strings.Contains(got, want) { 265 t.Errorf("missing %s", want) 266 } 267 } 268 } 269 270 func TestCgoTracebackContext(t *testing.T) { 271 t.Parallel() 272 got := runTestProg(t, "testprogcgo", "TracebackContext") 273 want := "OK\n" 274 if got != want { 275 t.Errorf("expected %q got %v", want, got) 276 } 277 } 278 279 func TestCgoTracebackContextPreemption(t *testing.T) { 280 t.Parallel() 281 got := runTestProg(t, "testprogcgo", "TracebackContextPreemption") 282 want := "OK\n" 283 if got != want { 284 t.Errorf("expected %q got %v", want, got) 285 } 286 } 287 288 func testCgoPprof(t *testing.T, buildArg, runArg, top, bottom string) { 289 t.Parallel() 290 if runtime.GOOS != "linux" || (runtime.GOARCH != "amd64" && runtime.GOARCH != "ppc64le" && runtime.GOARCH != "arm64") { 291 t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH) 292 } 293 testenv.MustHaveGoRun(t) 294 295 exe, err := buildTestProg(t, "testprogcgo", buildArg) 296 if err != nil { 297 t.Fatal(err) 298 } 299 300 cmd := testenv.CleanCmdEnv(exec.Command(exe, runArg)) 301 got, err := cmd.CombinedOutput() 302 if err != nil { 303 if testenv.Builder() == "linux-amd64-alpine" { 304 // See Issue 18243 and Issue 19938. 305 t.Skipf("Skipping failing test on Alpine (golang.org/issue/18243). Ignoring error: %v", err) 306 } 307 t.Fatalf("%s\n\n%v", got, err) 308 } 309 fn := strings.TrimSpace(string(got)) 310 defer os.Remove(fn) 311 312 for try := 0; try < 2; try++ { 313 cmd := testenv.CleanCmdEnv(exec.Command(testenv.GoToolPath(t), "tool", "pprof", "-tagignore=ignore", "-traces")) 314 // Check that pprof works both with and without explicit executable on command line. 315 if try == 0 { 316 cmd.Args = append(cmd.Args, exe, fn) 317 } else { 318 cmd.Args = append(cmd.Args, fn) 319 } 320 321 found := false 322 for i, e := range cmd.Env { 323 if strings.HasPrefix(e, "PPROF_TMPDIR=") { 324 cmd.Env[i] = "PPROF_TMPDIR=" + os.TempDir() 325 found = true 326 break 327 } 328 } 329 if !found { 330 cmd.Env = append(cmd.Env, "PPROF_TMPDIR="+os.TempDir()) 331 } 332 333 out, err := cmd.CombinedOutput() 334 t.Logf("%s:\n%s", cmd.Args, out) 335 if err != nil { 336 t.Error(err) 337 continue 338 } 339 340 trace := findTrace(string(out), top) 341 if len(trace) == 0 { 342 t.Errorf("%s traceback missing.", top) 343 continue 344 } 345 if trace[len(trace)-1] != bottom { 346 t.Errorf("invalid traceback origin: got=%v; want=[%s ... %s]", trace, top, bottom) 347 } 348 } 349 } 350 351 func TestCgoPprof(t *testing.T) { 352 testCgoPprof(t, "", "CgoPprof", "cpuHog", "runtime.main") 353 } 354 355 func TestCgoPprofPIE(t *testing.T) { 356 testCgoPprof(t, "-buildmode=pie", "CgoPprof", "cpuHog", "runtime.main") 357 } 358 359 func TestCgoPprofThread(t *testing.T) { 360 testCgoPprof(t, "", "CgoPprofThread", "cpuHogThread", "cpuHogThread2") 361 } 362 363 func TestCgoPprofThreadNoTraceback(t *testing.T) { 364 testCgoPprof(t, "", "CgoPprofThreadNoTraceback", "cpuHogThread", "runtime._ExternalCode") 365 } 366 367 func TestRaceProf(t *testing.T) { 368 if (runtime.GOOS != "linux" && runtime.GOOS != "freebsd") || runtime.GOARCH != "amd64" { 369 t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH) 370 } 371 372 testenv.MustHaveGoRun(t) 373 374 // This test requires building various packages with -race, so 375 // it's somewhat slow. 376 if testing.Short() { 377 t.Skip("skipping test in -short mode") 378 } 379 380 exe, err := buildTestProg(t, "testprogcgo", "-race") 381 if err != nil { 382 t.Fatal(err) 383 } 384 385 got, err := testenv.CleanCmdEnv(exec.Command(exe, "CgoRaceprof")).CombinedOutput() 386 if err != nil { 387 t.Fatal(err) 388 } 389 want := "OK\n" 390 if string(got) != want { 391 t.Errorf("expected %q got %s", want, got) 392 } 393 } 394 395 func TestRaceSignal(t *testing.T) { 396 t.Parallel() 397 if (runtime.GOOS != "linux" && runtime.GOOS != "freebsd") || runtime.GOARCH != "amd64" { 398 t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH) 399 } 400 401 testenv.MustHaveGoRun(t) 402 403 // This test requires building various packages with -race, so 404 // it's somewhat slow. 405 if testing.Short() { 406 t.Skip("skipping test in -short mode") 407 } 408 409 exe, err := buildTestProg(t, "testprogcgo", "-race") 410 if err != nil { 411 t.Fatal(err) 412 } 413 414 got, err := testenv.CleanCmdEnv(exec.Command(exe, "CgoRaceSignal")).CombinedOutput() 415 if err != nil { 416 t.Logf("%s\n", got) 417 t.Fatal(err) 418 } 419 want := "OK\n" 420 if string(got) != want { 421 t.Errorf("expected %q got %s", want, got) 422 } 423 } 424 425 func TestCgoNumGoroutine(t *testing.T) { 426 switch runtime.GOOS { 427 case "windows", "plan9": 428 t.Skipf("skipping numgoroutine test on %s", runtime.GOOS) 429 } 430 t.Parallel() 431 got := runTestProg(t, "testprogcgo", "NumGoroutine") 432 want := "OK\n" 433 if got != want { 434 t.Errorf("expected %q got %v", want, got) 435 } 436 } 437 438 func TestCatchPanic(t *testing.T) { 439 t.Parallel() 440 switch runtime.GOOS { 441 case "plan9", "windows": 442 t.Skipf("no signals on %s", runtime.GOOS) 443 case "darwin": 444 if runtime.GOARCH == "amd64" { 445 t.Skipf("crash() on darwin/amd64 doesn't raise SIGABRT") 446 } 447 } 448 449 testenv.MustHaveGoRun(t) 450 451 exe, err := buildTestProg(t, "testprogcgo") 452 if err != nil { 453 t.Fatal(err) 454 } 455 456 for _, early := range []bool{true, false} { 457 cmd := testenv.CleanCmdEnv(exec.Command(exe, "CgoCatchPanic")) 458 // Make sure a panic results in a crash. 459 cmd.Env = append(cmd.Env, "GOTRACEBACK=crash") 460 if early { 461 // Tell testprogcgo to install an early signal handler for SIGABRT 462 cmd.Env = append(cmd.Env, "CGOCATCHPANIC_EARLY_HANDLER=1") 463 } 464 if out, err := cmd.CombinedOutput(); err != nil { 465 t.Errorf("testprogcgo CgoCatchPanic failed: %v\n%s", err, out) 466 } 467 } 468 } 469 470 func TestCgoLockOSThreadExit(t *testing.T) { 471 switch runtime.GOOS { 472 case "plan9", "windows": 473 t.Skipf("no pthreads on %s", runtime.GOOS) 474 } 475 t.Parallel() 476 testLockOSThreadExit(t, "testprogcgo") 477 } 478 479 func TestWindowsStackMemoryCgo(t *testing.T) { 480 if runtime.GOOS != "windows" { 481 t.Skip("skipping windows specific test") 482 } 483 testenv.SkipFlaky(t, 22575) 484 o := runTestProg(t, "testprogcgo", "StackMemory") 485 stackUsage, err := strconv.Atoi(o) 486 if err != nil { 487 t.Fatalf("Failed to read stack usage: %v", err) 488 } 489 if expected, got := 100<<10, stackUsage; got > expected { 490 t.Fatalf("expected < %d bytes of memory per thread, got %d", expected, got) 491 } 492 } 493 494 func TestSigStackSwapping(t *testing.T) { 495 switch runtime.GOOS { 496 case "plan9", "windows": 497 t.Skipf("no sigaltstack on %s", runtime.GOOS) 498 } 499 t.Parallel() 500 got := runTestProg(t, "testprogcgo", "SigStack") 501 want := "OK\n" 502 if got != want { 503 t.Errorf("expected %q got %v", want, got) 504 } 505 } 506 507 func TestCgoTracebackSigpanic(t *testing.T) { 508 // Test unwinding over a sigpanic in C code without a C 509 // symbolizer. See issue #23576. 510 if runtime.GOOS == "windows" { 511 // On Windows if we get an exception in C code, we let 512 // the Windows exception handler unwind it, rather 513 // than injecting a sigpanic. 514 t.Skip("no sigpanic in C on windows") 515 } 516 t.Parallel() 517 got := runTestProg(t, "testprogcgo", "TracebackSigpanic") 518 t.Log(got) 519 want := "runtime.sigpanic" 520 if !strings.Contains(got, want) { 521 t.Errorf("did not see %q in output", want) 522 } 523 // No runtime errors like "runtime: unexpected return pc". 524 nowant := "runtime: " 525 if strings.Contains(got, nowant) { 526 t.Errorf("unexpectedly saw %q in output", nowant) 527 } 528 } 529 530 func TestCgoPanicCallback(t *testing.T) { 531 t.Parallel() 532 got := runTestProg(t, "testprogcgo", "PanicCallback") 533 t.Log(got) 534 want := "panic: runtime error: invalid memory address or nil pointer dereference" 535 if !strings.Contains(got, want) { 536 t.Errorf("did not see %q in output", want) 537 } 538 want = "panic_callback" 539 if !strings.Contains(got, want) { 540 t.Errorf("did not see %q in output", want) 541 } 542 want = "PanicCallback" 543 if !strings.Contains(got, want) { 544 t.Errorf("did not see %q in output", want) 545 } 546 // No runtime errors like "runtime: unexpected return pc". 547 nowant := "runtime: " 548 if strings.Contains(got, nowant) { 549 t.Errorf("did not see %q in output", want) 550 } 551 } 552 553 // Test that C code called via cgo can use large Windows thread stacks 554 // and call back in to Go without crashing. See issue #20975. 555 // 556 // See also TestBigStackCallbackSyscall. 557 func TestBigStackCallbackCgo(t *testing.T) { 558 if runtime.GOOS != "windows" { 559 t.Skip("skipping windows specific test") 560 } 561 t.Parallel() 562 got := runTestProg(t, "testprogcgo", "BigStack") 563 want := "OK\n" 564 if got != want { 565 t.Errorf("expected %q got %v", want, got) 566 } 567 } 568 569 func nextTrace(lines []string) ([]string, []string) { 570 var trace []string 571 for n, line := range lines { 572 if strings.HasPrefix(line, "---") { 573 return trace, lines[n+1:] 574 } 575 fields := strings.Fields(strings.TrimSpace(line)) 576 if len(fields) == 0 { 577 continue 578 } 579 // Last field contains the function name. 580 trace = append(trace, fields[len(fields)-1]) 581 } 582 return nil, nil 583 } 584 585 func findTrace(text, top string) []string { 586 lines := strings.Split(text, "\n") 587 _, lines = nextTrace(lines) // Skip the header. 588 for len(lines) > 0 { 589 var t []string 590 t, lines = nextTrace(lines) 591 if len(t) == 0 { 592 continue 593 } 594 if t[0] == top { 595 return t 596 } 597 } 598 return nil 599 } 600 601 func TestSegv(t *testing.T) { 602 switch runtime.GOOS { 603 case "plan9", "windows": 604 t.Skipf("no signals on %s", runtime.GOOS) 605 } 606 607 for _, test := range []string{"Segv", "SegvInCgo", "TgkillSegv", "TgkillSegvInCgo"} { 608 test := test 609 610 // The tgkill variants only run on Linux. 611 if runtime.GOOS != "linux" && strings.HasPrefix(test, "Tgkill") { 612 continue 613 } 614 615 t.Run(test, func(t *testing.T) { 616 t.Parallel() 617 got := runTestProg(t, "testprogcgo", test) 618 t.Log(got) 619 want := "SIGSEGV" 620 if !strings.Contains(got, want) { 621 if runtime.GOOS == "darwin" && runtime.GOARCH == "amd64" && strings.Contains(got, "fatal: morestack on g0") { 622 testenv.SkipFlaky(t, 39457) 623 } 624 t.Errorf("did not see %q in output", want) 625 } 626 627 // No runtime errors like "runtime: unknown pc". 628 switch runtime.GOOS { 629 case "darwin", "illumos", "solaris": 630 // Runtime sometimes throws when generating the traceback. 631 testenv.SkipFlaky(t, 49182) 632 case "linux": 633 if runtime.GOARCH == "386" { 634 // Runtime throws when generating a traceback from 635 // a VDSO call via asmcgocall. 636 testenv.SkipFlaky(t, 50504) 637 } 638 } 639 if test == "SegvInCgo" && strings.Contains(got, "unknown pc") { 640 testenv.SkipFlaky(t, 50979) 641 } 642 643 for _, nowant := range []string{"fatal error: ", "runtime: "} { 644 if strings.Contains(got, nowant) { 645 if runtime.GOOS == "darwin" && strings.Contains(got, "0xb01dfacedebac1e") { 646 // See the comment in signal_darwin_amd64.go. 647 t.Skip("skipping due to Darwin handling of malformed addresses") 648 } 649 t.Errorf("unexpectedly saw %q in output", nowant) 650 } 651 } 652 }) 653 } 654 } 655 656 func TestAbortInCgo(t *testing.T) { 657 switch runtime.GOOS { 658 case "plan9", "windows": 659 // N.B. On Windows, C abort() causes the program to exit 660 // without going through the runtime at all. 661 t.Skipf("no signals on %s", runtime.GOOS) 662 } 663 664 t.Parallel() 665 got := runTestProg(t, "testprogcgo", "Abort") 666 t.Log(got) 667 want := "SIGABRT" 668 if !strings.Contains(got, want) { 669 t.Errorf("did not see %q in output", want) 670 } 671 // No runtime errors like "runtime: unknown pc". 672 nowant := "runtime: " 673 if strings.Contains(got, nowant) { 674 t.Errorf("did not see %q in output", want) 675 } 676 } 677 678 // TestEINTR tests that we handle EINTR correctly. 679 // See issue #20400 and friends. 680 func TestEINTR(t *testing.T) { 681 switch runtime.GOOS { 682 case "plan9", "windows": 683 t.Skipf("no EINTR on %s", runtime.GOOS) 684 case "linux": 685 if runtime.GOARCH == "386" { 686 // On linux-386 the Go signal handler sets 687 // a restorer function that is not preserved 688 // by the C sigaction call in the test, 689 // causing the signal handler to crash when 690 // returning the normal code. The test is not 691 // architecture-specific, so just skip on 386 692 // rather than doing a complicated workaround. 693 t.Skip("skipping on linux-386; C sigaction does not preserve Go restorer") 694 } 695 } 696 697 t.Parallel() 698 output := runTestProg(t, "testprogcgo", "EINTR") 699 want := "OK\n" 700 if output != want { 701 t.Fatalf("want %s, got %s\n", want, output) 702 } 703 } 704 705 // Issue #42207. 706 func TestNeedmDeadlock(t *testing.T) { 707 switch runtime.GOOS { 708 case "plan9", "windows": 709 t.Skipf("no signals on %s", runtime.GOOS) 710 } 711 output := runTestProg(t, "testprogcgo", "NeedmDeadlock") 712 want := "OK\n" 713 if output != want { 714 t.Fatalf("want %s, got %s\n", want, output) 715 } 716 } 717 718 func TestCgoTracebackGoroutineProfile(t *testing.T) { 719 output := runTestProg(t, "testprogcgo", "GoroutineProfile") 720 want := "OK\n" 721 if output != want { 722 t.Fatalf("want %s, got %s\n", want, output) 723 } 724 } 725 726 func TestCgoTraceParser(t *testing.T) { 727 // Test issue 29707. 728 switch runtime.GOOS { 729 case "plan9", "windows": 730 t.Skipf("no pthreads on %s", runtime.GOOS) 731 } 732 output := runTestProg(t, "testprogcgo", "CgoTraceParser") 733 want := "OK\n" 734 ErrTimeOrder := "ErrTimeOrder\n" 735 if output == ErrTimeOrder { 736 t.Skipf("skipping due to golang.org/issue/16755: %v", output) 737 } else if output != want { 738 t.Fatalf("want %s, got %s\n", want, output) 739 } 740 } 741 742 func TestCgoTraceParserWithOneProc(t *testing.T) { 743 // Test issue 29707. 744 switch runtime.GOOS { 745 case "plan9", "windows": 746 t.Skipf("no pthreads on %s", runtime.GOOS) 747 } 748 output := runTestProg(t, "testprogcgo", "CgoTraceParser", "GOMAXPROCS=1") 749 want := "OK\n" 750 ErrTimeOrder := "ErrTimeOrder\n" 751 if output == ErrTimeOrder { 752 t.Skipf("skipping due to golang.org/issue/16755: %v", output) 753 } else if output != want { 754 t.Fatalf("GOMAXPROCS=1, want %s, got %s\n", want, output) 755 } 756 } 757 758 func TestCgoSigfwd(t *testing.T) { 759 t.Parallel() 760 if !goos.IsUnix { 761 t.Skipf("no signals on %s", runtime.GOOS) 762 } 763 764 got := runTestProg(t, "testprogcgo", "CgoSigfwd", "GO_TEST_CGOSIGFWD=1") 765 if want := "OK\n"; got != want { 766 t.Fatalf("expected %q, but got:\n%s", want, got) 767 } 768 }