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.
23 func TestCgoCrashHandler(t *testing.T) {
25 testCrashHandler(t, true)
28 func TestCgoSignalDeadlock(t *testing.T) {
29 // Don't call t.Parallel, since too much work going on at the
30 // same time can cause the testprogcgo code to overrun its
31 // timeouts (issue #18598).
33 if testing.Short() && runtime.GOOS == "windows" {
34 t.Skip("Skipping in short mode") // takes up to 64 seconds
36 got := runTestProg(t, "testprogcgo", "CgoSignalDeadlock")
39 t.Fatalf("expected %q, but got:\n%s", want, got)
43 func TestCgoTraceback(t *testing.T) {
45 got := runTestProg(t, "testprogcgo", "CgoTraceback")
48 t.Fatalf("expected %q, but got:\n%s", want, got)
52 func TestCgoCallbackGC(t *testing.T) {
55 case "plan9", "windows":
56 t.Skipf("no pthreads on %s", runtime.GOOS)
60 case runtime.GOOS == "dragonfly":
61 t.Skip("see golang.org/issue/11990")
62 case runtime.GOOS == "linux" && runtime.GOARCH == "arm":
63 t.Skip("too slow for arm builders")
64 case runtime.GOOS == "linux" && (runtime.GOARCH == "mips64" || runtime.GOARCH == "mips64le"):
65 t.Skip("too slow for mips64x builders")
68 if testenv.Builder() == "darwin-amd64-10_14" {
69 // TODO(#23011): When the 10.14 builders are gone, remove this skip.
70 t.Skip("skipping due to platform bug on macOS 10.14; see https://golang.org/issue/43926")
72 got := runTestProg(t, "testprogcgo", "CgoCallbackGC")
75 t.Fatalf("expected %q, but got:\n%s", want, got)
79 func TestCgoExternalThreadPanic(t *testing.T) {
81 if runtime.GOOS == "plan9" {
82 t.Skipf("no pthreads on %s", runtime.GOOS)
84 got := runTestProg(t, "testprogcgo", "CgoExternalThreadPanic")
86 if !strings.Contains(got, want) {
87 t.Fatalf("want failure containing %q. output:\n%s\n", want, got)
91 func TestCgoExternalThreadSIGPROF(t *testing.T) {
95 case "plan9", "windows":
96 t.Skipf("no pthreads on %s", runtime.GOOS)
99 got := runTestProg(t, "testprogcgo", "CgoExternalThreadSIGPROF", "GO_START_SIGPROF_THREAD=1")
100 if want := "OK\n"; got != want {
101 t.Fatalf("expected %q, but got:\n%s", want, got)
105 func TestCgoExternalThreadSignal(t *testing.T) {
108 switch runtime.GOOS {
109 case "plan9", "windows":
110 t.Skipf("no pthreads on %s", runtime.GOOS)
113 got := runTestProg(t, "testprogcgo", "CgoExternalThreadSignal")
114 if want := "OK\n"; got != want {
115 if runtime.GOOS == "ios" && strings.Contains(got, "C signal did not crash as expected") {
116 testenv.SkipFlaky(t, 59913)
118 t.Fatalf("expected %q, but got:\n%s", want, got)
122 func TestCgoDLLImports(t *testing.T) {
124 if runtime.GOOS != "windows" {
125 t.Skip("skipping windows specific test")
127 got := runTestProg(t, "testprogcgo", "CgoDLLImportsMain")
130 t.Fatalf("expected %q, but got %v", want, got)
134 func TestCgoExecSignalMask(t *testing.T) {
137 switch runtime.GOOS {
138 case "windows", "plan9":
139 t.Skipf("skipping signal mask test on %s", runtime.GOOS)
141 got := runTestProg(t, "testprogcgo", "CgoExecSignalMask", "GOTRACEBACK=system")
144 t.Errorf("expected %q, got %v", want, got)
148 func TestEnsureDropM(t *testing.T) {
150 // Test for issue 13881.
151 switch runtime.GOOS {
152 case "windows", "plan9":
153 t.Skipf("skipping dropm test on %s", runtime.GOOS)
155 got := runTestProg(t, "testprogcgo", "EnsureDropM")
158 t.Errorf("expected %q, got %v", want, got)
162 // Test for issue 14387.
163 // Test that the program that doesn't need any cgo pointer checking
164 // takes about the same amount of time with it as without it.
165 func TestCgoCheckBytes(t *testing.T) {
167 // Make sure we don't count the build time as part of the run time.
168 testenv.MustHaveGoBuild(t)
169 exe, err := buildTestProg(t, "testprogcgo")
174 // Try it 10 times to avoid flakiness.
176 var tot1, tot2 time.Duration
177 for i := 0; i < tries; i++ {
178 cmd := testenv.CleanCmdEnv(exec.Command(exe, "CgoCheckBytes"))
179 cmd.Env = append(cmd.Env, "GODEBUG=cgocheck=0", fmt.Sprintf("GO_CGOCHECKBYTES_TRY=%d", i))
183 d1 := time.Since(start)
185 cmd = testenv.CleanCmdEnv(exec.Command(exe, "CgoCheckBytes"))
186 cmd.Env = append(cmd.Env, fmt.Sprintf("GO_CGOCHECKBYTES_TRY=%d", i))
190 d2 := time.Since(start)
193 // The slow version (d2) was less than 20 times
194 // slower than the fast version (d1), so OK.
202 t.Errorf("cgo check too slow: got %v, expected at most %v", tot2/tries, (tot1/tries)*20)
205 func TestCgoPanicDeadlock(t *testing.T) {
208 got := runTestProg(t, "testprogcgo", "CgoPanicDeadlock")
209 want := "panic: cgo error\n\n"
210 if !strings.HasPrefix(got, want) {
211 t.Fatalf("output does not start with %q:\n%s", want, got)
215 func TestCgoCCodeSIGPROF(t *testing.T) {
217 got := runTestProg(t, "testprogcgo", "CgoCCodeSIGPROF")
220 t.Errorf("expected %q got %v", want, got)
224 func TestCgoPprofCallback(t *testing.T) {
226 t.Skip("skipping in short mode") // takes a full second
228 switch runtime.GOOS {
229 case "windows", "plan9":
230 t.Skipf("skipping cgo pprof callback test on %s", runtime.GOOS)
232 got := runTestProg(t, "testprogcgo", "CgoPprofCallback")
235 t.Errorf("expected %q got %v", want, got)
239 func TestCgoCrashTraceback(t *testing.T) {
241 switch platform := runtime.GOOS + "/" + runtime.GOARCH; platform {
245 case "linux/ppc64le":
247 t.Skipf("not yet supported on %s", platform)
249 got := runTestProg(t, "testprogcgo", "CrashTraceback")
250 for i := 1; i <= 3; i++ {
251 if !strings.Contains(got, fmt.Sprintf("cgo symbolizer:%d", i)) {
252 t.Errorf("missing cgo symbolizer:%d", i)
257 func TestCgoCrashTracebackGo(t *testing.T) {
259 switch platform := runtime.GOOS + "/" + runtime.GOARCH; platform {
263 case "linux/ppc64le":
265 t.Skipf("not yet supported on %s", platform)
267 got := runTestProg(t, "testprogcgo", "CrashTracebackGo")
268 for i := 1; i <= 3; i++ {
269 want := fmt.Sprintf("main.h%d", i)
270 if !strings.Contains(got, want) {
271 t.Errorf("missing %s", want)
276 func TestCgoTracebackContext(t *testing.T) {
278 got := runTestProg(t, "testprogcgo", "TracebackContext")
281 t.Errorf("expected %q got %v", want, got)
285 func TestCgoTracebackContextPreemption(t *testing.T) {
287 got := runTestProg(t, "testprogcgo", "TracebackContextPreemption")
290 t.Errorf("expected %q got %v", want, got)
294 func testCgoPprof(t *testing.T, buildArg, runArg, top, bottom string) {
296 if runtime.GOOS != "linux" || (runtime.GOARCH != "amd64" && runtime.GOARCH != "ppc64le" && runtime.GOARCH != "arm64") {
297 t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH)
299 testenv.MustHaveGoRun(t)
301 exe, err := buildTestProg(t, "testprogcgo", buildArg)
306 cmd := testenv.CleanCmdEnv(exec.Command(exe, runArg))
307 got, err := cmd.CombinedOutput()
309 if testenv.Builder() == "linux-amd64-alpine" {
310 // See Issue 18243 and Issue 19938.
311 t.Skipf("Skipping failing test on Alpine (golang.org/issue/18243). Ignoring error: %v", err)
313 t.Fatalf("%s\n\n%v", got, err)
315 fn := strings.TrimSpace(string(got))
318 for try := 0; try < 2; try++ {
319 cmd := testenv.CleanCmdEnv(exec.Command(testenv.GoToolPath(t), "tool", "pprof", "-tagignore=ignore", "-traces"))
320 // Check that pprof works both with and without explicit executable on command line.
322 cmd.Args = append(cmd.Args, exe, fn)
324 cmd.Args = append(cmd.Args, fn)
328 for i, e := range cmd.Env {
329 if strings.HasPrefix(e, "PPROF_TMPDIR=") {
330 cmd.Env[i] = "PPROF_TMPDIR=" + os.TempDir()
336 cmd.Env = append(cmd.Env, "PPROF_TMPDIR="+os.TempDir())
339 out, err := cmd.CombinedOutput()
340 t.Logf("%s:\n%s", cmd.Args, out)
346 trace := findTrace(string(out), top)
348 t.Errorf("%s traceback missing.", top)
351 if trace[len(trace)-1] != bottom {
352 t.Errorf("invalid traceback origin: got=%v; want=[%s ... %s]", trace, top, bottom)
357 func TestCgoPprof(t *testing.T) {
358 testCgoPprof(t, "", "CgoPprof", "cpuHog", "runtime.main")
361 func TestCgoPprofPIE(t *testing.T) {
362 testCgoPprof(t, "-buildmode=pie", "CgoPprof", "cpuHog", "runtime.main")
365 func TestCgoPprofThread(t *testing.T) {
366 testCgoPprof(t, "", "CgoPprofThread", "cpuHogThread", "cpuHogThread2")
369 func TestCgoPprofThreadNoTraceback(t *testing.T) {
370 testCgoPprof(t, "", "CgoPprofThreadNoTraceback", "cpuHogThread", "runtime._ExternalCode")
373 func TestRaceProf(t *testing.T) {
374 if !platform.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH) {
375 t.Skipf("skipping on %s/%s because race detector not supported", runtime.GOOS, runtime.GOARCH)
377 if runtime.GOOS == "windows" {
378 t.Skipf("skipping: test requires pthread support")
379 // TODO: Can this test be rewritten to use the C11 thread API instead?
382 testenv.MustHaveGoRun(t)
384 // This test requires building various packages with -race, so
385 // it's somewhat slow.
387 t.Skip("skipping test in -short mode")
390 exe, err := buildTestProg(t, "testprogcgo", "-race")
395 got, err := testenv.CleanCmdEnv(exec.Command(exe, "CgoRaceprof")).CombinedOutput()
400 if string(got) != want {
401 t.Errorf("expected %q got %s", want, got)
405 func TestRaceSignal(t *testing.T) {
406 if !platform.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH) {
407 t.Skipf("skipping on %s/%s because race detector not supported", runtime.GOOS, runtime.GOARCH)
409 if runtime.GOOS == "windows" {
410 t.Skipf("skipping: test requires pthread support")
411 // TODO: Can this test be rewritten to use the C11 thread API instead?
413 if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
414 testenv.SkipFlaky(t, 60316)
419 testenv.MustHaveGoRun(t)
421 // This test requires building various packages with -race, so
422 // it's somewhat slow.
424 t.Skip("skipping test in -short mode")
427 exe, err := buildTestProg(t, "testprogcgo", "-race")
432 got, err := testenv.CleanCmdEnv(testenv.Command(t, exe, "CgoRaceSignal")).CombinedOutput()
438 if string(got) != want {
439 t.Errorf("expected %q got %s", want, got)
443 func TestCgoNumGoroutine(t *testing.T) {
444 switch runtime.GOOS {
445 case "windows", "plan9":
446 t.Skipf("skipping numgoroutine test on %s", runtime.GOOS)
449 got := runTestProg(t, "testprogcgo", "NumGoroutine")
452 t.Errorf("expected %q got %v", want, got)
456 func TestCatchPanic(t *testing.T) {
458 switch runtime.GOOS {
459 case "plan9", "windows":
460 t.Skipf("no signals on %s", runtime.GOOS)
462 if runtime.GOARCH == "amd64" {
463 t.Skipf("crash() on darwin/amd64 doesn't raise SIGABRT")
467 testenv.MustHaveGoRun(t)
469 exe, err := buildTestProg(t, "testprogcgo")
474 for _, early := range []bool{true, false} {
475 cmd := testenv.CleanCmdEnv(exec.Command(exe, "CgoCatchPanic"))
476 // Make sure a panic results in a crash.
477 cmd.Env = append(cmd.Env, "GOTRACEBACK=crash")
479 // Tell testprogcgo to install an early signal handler for SIGABRT
480 cmd.Env = append(cmd.Env, "CGOCATCHPANIC_EARLY_HANDLER=1")
482 if out, err := cmd.CombinedOutput(); err != nil {
483 t.Errorf("testprogcgo CgoCatchPanic failed: %v\n%s", err, out)
488 func TestCgoLockOSThreadExit(t *testing.T) {
489 switch runtime.GOOS {
490 case "plan9", "windows":
491 t.Skipf("no pthreads on %s", runtime.GOOS)
494 testLockOSThreadExit(t, "testprogcgo")
497 func TestWindowsStackMemoryCgo(t *testing.T) {
498 if runtime.GOOS != "windows" {
499 t.Skip("skipping windows specific test")
501 testenv.SkipFlaky(t, 22575)
502 o := runTestProg(t, "testprogcgo", "StackMemory")
503 stackUsage, err := strconv.Atoi(o)
505 t.Fatalf("Failed to read stack usage: %v", err)
507 if expected, got := 100<<10, stackUsage; got > expected {
508 t.Fatalf("expected < %d bytes of memory per thread, got %d", expected, got)
512 func TestSigStackSwapping(t *testing.T) {
513 switch runtime.GOOS {
514 case "plan9", "windows":
515 t.Skipf("no sigaltstack on %s", runtime.GOOS)
518 got := runTestProg(t, "testprogcgo", "SigStack")
521 t.Errorf("expected %q got %v", want, got)
525 func TestCgoTracebackSigpanic(t *testing.T) {
526 // Test unwinding over a sigpanic in C code without a C
527 // symbolizer. See issue #23576.
528 if runtime.GOOS == "windows" {
529 // On Windows if we get an exception in C code, we let
530 // the Windows exception handler unwind it, rather
531 // than injecting a sigpanic.
532 t.Skip("no sigpanic in C on windows")
534 if runtime.GOOS == "ios" {
535 testenv.SkipFlaky(t, 59912)
538 got := runTestProg(t, "testprogcgo", "TracebackSigpanic")
540 // We should see the function that calls the C function.
541 want := "main.TracebackSigpanic"
542 if !strings.Contains(got, want) {
543 if runtime.GOOS == "android" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
544 testenv.SkipFlaky(t, 58794)
546 t.Errorf("did not see %q in output", want)
548 // We shouldn't inject a sigpanic call. (see issue 57698)
549 nowant := "runtime.sigpanic"
550 if strings.Contains(got, nowant) {
551 t.Errorf("unexpectedly saw %q in output", nowant)
553 // No runtime errors like "runtime: unexpected return pc".
555 if strings.Contains(got, nowant) {
556 t.Errorf("unexpectedly saw %q in output", nowant)
560 func TestCgoPanicCallback(t *testing.T) {
562 got := runTestProg(t, "testprogcgo", "PanicCallback")
564 want := "panic: runtime error: invalid memory address or nil pointer dereference"
565 if !strings.Contains(got, want) {
566 t.Errorf("did not see %q in output", want)
568 want = "panic_callback"
569 if !strings.Contains(got, want) {
570 t.Errorf("did not see %q in output", want)
572 want = "PanicCallback"
573 if !strings.Contains(got, want) {
574 t.Errorf("did not see %q in output", want)
576 // No runtime errors like "runtime: unexpected return pc".
577 nowant := "runtime: "
578 if strings.Contains(got, nowant) {
579 t.Errorf("did not see %q in output", want)
583 // Test that C code called via cgo can use large Windows thread stacks
584 // and call back in to Go without crashing. See issue #20975.
586 // See also TestBigStackCallbackSyscall.
587 func TestBigStackCallbackCgo(t *testing.T) {
588 if runtime.GOOS != "windows" {
589 t.Skip("skipping windows specific test")
592 got := runTestProg(t, "testprogcgo", "BigStack")
595 t.Errorf("expected %q got %v", want, got)
599 func nextTrace(lines []string) ([]string, []string) {
601 for n, line := range lines {
602 if strings.HasPrefix(line, "---") {
603 return trace, lines[n+1:]
605 fields := strings.Fields(strings.TrimSpace(line))
606 if len(fields) == 0 {
609 // Last field contains the function name.
610 trace = append(trace, fields[len(fields)-1])
615 func findTrace(text, top string) []string {
616 lines := strings.Split(text, "\n")
617 _, lines = nextTrace(lines) // Skip the header.
620 t, lines = nextTrace(lines)
631 func TestSegv(t *testing.T) {
632 switch runtime.GOOS {
633 case "plan9", "windows":
634 t.Skipf("no signals on %s", runtime.GOOS)
637 for _, test := range []string{"Segv", "SegvInCgo", "TgkillSegv", "TgkillSegvInCgo"} {
640 // The tgkill variants only run on Linux.
641 if runtime.GOOS != "linux" && strings.HasPrefix(test, "Tgkill") {
645 t.Run(test, func(t *testing.T) {
646 if test == "SegvInCgo" && runtime.GOOS == "ios" {
647 testenv.SkipFlaky(t, 59947) // Don't even try, in case it times out.
652 if strings.HasSuffix(test, "InCgo") {
655 got := runTestProg(t, prog, test)
658 if !strings.Contains(got, want) {
659 if runtime.GOOS == "darwin" && runtime.GOARCH == "amd64" && strings.Contains(got, "fatal: morestack on g0") {
660 testenv.SkipFlaky(t, 39457)
662 t.Errorf("did not see %q in output", want)
665 // No runtime errors like "runtime: unknown pc".
666 switch runtime.GOOS {
667 case "darwin", "ios", "illumos", "solaris":
668 // Runtime sometimes throws when generating the traceback.
669 testenv.SkipFlaky(t, 49182)
671 if runtime.GOARCH == "386" {
672 // Runtime throws when generating a traceback from
673 // a VDSO call via asmcgocall.
674 testenv.SkipFlaky(t, 50504)
677 if test == "SegvInCgo" && strings.Contains(got, "unknown pc") {
678 testenv.SkipFlaky(t, 50979)
681 for _, nowant := range []string{"fatal error: ", "runtime: "} {
682 if strings.Contains(got, nowant) {
683 if runtime.GOOS == "darwin" && strings.Contains(got, "0xb01dfacedebac1e") {
684 // See the comment in signal_darwin_amd64.go.
685 t.Skip("skipping due to Darwin handling of malformed addresses")
687 t.Errorf("unexpectedly saw %q in output", nowant)
694 func TestAbortInCgo(t *testing.T) {
695 switch runtime.GOOS {
696 case "plan9", "windows":
697 // N.B. On Windows, C abort() causes the program to exit
698 // without going through the runtime at all.
699 t.Skipf("no signals on %s", runtime.GOOS)
703 got := runTestProg(t, "testprogcgo", "Abort")
706 if !strings.Contains(got, want) {
707 t.Errorf("did not see %q in output", want)
709 // No runtime errors like "runtime: unknown pc".
710 nowant := "runtime: "
711 if strings.Contains(got, nowant) {
712 t.Errorf("did not see %q in output", want)
716 // TestEINTR tests that we handle EINTR correctly.
717 // See issue #20400 and friends.
718 func TestEINTR(t *testing.T) {
719 switch runtime.GOOS {
720 case "plan9", "windows":
721 t.Skipf("no EINTR on %s", runtime.GOOS)
723 if runtime.GOARCH == "386" {
724 // On linux-386 the Go signal handler sets
725 // a restorer function that is not preserved
726 // by the C sigaction call in the test,
727 // causing the signal handler to crash when
728 // returning the normal code. The test is not
729 // architecture-specific, so just skip on 386
730 // rather than doing a complicated workaround.
731 t.Skip("skipping on linux-386; C sigaction does not preserve Go restorer")
736 output := runTestProg(t, "testprogcgo", "EINTR")
739 t.Fatalf("want %s, got %s\n", want, output)
744 func TestNeedmDeadlock(t *testing.T) {
745 switch runtime.GOOS {
746 case "plan9", "windows":
747 t.Skipf("no signals on %s", runtime.GOOS)
749 output := runTestProg(t, "testprogcgo", "NeedmDeadlock")
752 t.Fatalf("want %s, got %s\n", want, output)
756 func TestCgoNoCallback(t *testing.T) {
757 t.Skip("TODO(#56378): enable in Go 1.23")
758 got := runTestProg(t, "testprogcgo", "CgoNoCallback")
759 want := "function marked with #cgo nocallback called back into Go"
760 if !strings.Contains(got, want) {
761 t.Fatalf("did not see %q in output:\n%s", want, got)
765 func TestCgoNoEscape(t *testing.T) {
766 t.Skip("TODO(#56378): enable in Go 1.23")
767 got := runTestProg(t, "testprogcgo", "CgoNoEscape")
770 t.Fatalf("want %s, got %s\n", want, got)
774 func TestCgoTracebackGoroutineProfile(t *testing.T) {
775 output := runTestProg(t, "testprogcgo", "GoroutineProfile")
778 t.Fatalf("want %s, got %s\n", want, output)
782 func TestCgoTraceParser(t *testing.T) {
784 switch runtime.GOOS {
785 case "plan9", "windows":
786 t.Skipf("no pthreads on %s", runtime.GOOS)
788 output := runTestProg(t, "testprogcgo", "CgoTraceParser")
790 ErrTimeOrder := "ErrTimeOrder\n"
791 if output == ErrTimeOrder {
792 t.Skipf("skipping due to golang.org/issue/16755: %v", output)
793 } else if output != want {
794 t.Fatalf("want %s, got %s\n", want, output)
798 func TestCgoTraceParserWithOneProc(t *testing.T) {
800 switch runtime.GOOS {
801 case "plan9", "windows":
802 t.Skipf("no pthreads on %s", runtime.GOOS)
804 output := runTestProg(t, "testprogcgo", "CgoTraceParser", "GOMAXPROCS=1")
806 ErrTimeOrder := "ErrTimeOrder\n"
807 if output == ErrTimeOrder {
808 t.Skipf("skipping due to golang.org/issue/16755: %v", output)
809 } else if output != want {
810 t.Fatalf("GOMAXPROCS=1, want %s, got %s\n", want, output)
814 func TestCgoSigfwd(t *testing.T) {
817 t.Skipf("no signals on %s", runtime.GOOS)
820 got := runTestProg(t, "testprogcgo", "CgoSigfwd", "GO_TEST_CGOSIGFWD=1")
821 if want := "OK\n"; got != want {
822 t.Fatalf("expected %q, but got:\n%s", want, got)
826 func TestDestructorCallback(t *testing.T) {
828 got := runTestProg(t, "testprogcgo", "DestructorCallback")
829 if want := "OK\n"; got != want {
830 t.Errorf("expected %q, but got:\n%s", want, got)
834 func TestDestructorCallbackRace(t *testing.T) {
835 // This test requires building with -race,
836 // so it's somewhat slow.
838 t.Skip("skipping test in -short mode")
841 if !platform.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH) {
842 t.Skipf("skipping on %s/%s because race detector not supported", runtime.GOOS, runtime.GOARCH)
847 exe, err := buildTestProg(t, "testprogcgo", "-race")
852 got, err := testenv.CleanCmdEnv(exec.Command(exe, "DestructorCallback")).CombinedOutput()
857 if want := "OK\n"; string(got) != want {
858 t.Errorf("expected %q, but got:\n%s", want, got)
862 func TestEnsureBindM(t *testing.T) {
864 switch runtime.GOOS {
865 case "windows", "plan9":
866 t.Skipf("skipping bindm test on %s", runtime.GOOS)
868 got := runTestProg(t, "testprogcgo", "EnsureBindM")
871 t.Errorf("expected %q, got %v", want, got)
875 func TestStackSwitchCallback(t *testing.T) {
877 switch runtime.GOOS {
878 case "windows", "plan9", "android", "ios", "openbsd": // no getcontext
879 t.Skipf("skipping test on %s", runtime.GOOS)
881 got := runTestProg(t, "testprogcgo", "StackSwitchCallback")
884 t.Skip("skipping on musl/bionic libc")
888 t.Errorf("expected %q, got %v", want, got)