diff options
Diffstat (limited to 'libgo/go/runtime/crash_cgo_test.go')
-rw-r--r-- | libgo/go/runtime/crash_cgo_test.go | 408 |
1 files changed, 38 insertions, 370 deletions
diff --git a/libgo/go/runtime/crash_cgo_test.go b/libgo/go/runtime/crash_cgo_test.go index 2e65e4c..d7b367f 100644 --- a/libgo/go/runtime/crash_cgo_test.go +++ b/libgo/go/runtime/crash_cgo_test.go @@ -21,18 +21,18 @@ func TestCgoSignalDeadlock(t *testing.T) { if testing.Short() && runtime.GOOS == "windows" { t.Skip("Skipping in short mode") // takes up to 64 seconds } - got := executeTest(t, cgoSignalDeadlockSource, nil) + got := runTestProg(t, "testprogcgo", "CgoSignalDeadlock") want := "OK\n" if got != want { - t.Fatalf("expected %q, but got %q", want, got) + t.Fatalf("expected %q, but got:\n%s", want, got) } } func TestCgoTraceback(t *testing.T) { - got := executeTest(t, cgoTracebackSource, nil) + got := runTestProg(t, "testprogcgo", "CgoTraceback") want := "OK\n" if got != want { - t.Fatalf("expected %q, but got %q", want, got) + t.Fatalf("expected %q, but got:\n%s", want, got) } } @@ -40,13 +40,18 @@ func TestCgoCallbackGC(t *testing.T) { if runtime.GOOS == "plan9" || runtime.GOOS == "windows" { t.Skipf("no pthreads on %s", runtime.GOOS) } - if testing.Short() && runtime.GOOS == "dragonfly" { - t.Skip("see golang.org/issue/11990") + if testing.Short() { + switch { + case runtime.GOOS == "dragonfly": + t.Skip("see golang.org/issue/11990") + case runtime.GOOS == "linux" && runtime.GOARCH == "arm": + t.Skip("too slow for arm builders") + } } - got := executeTest(t, cgoCallbackGCSource, nil) + got := runTestProg(t, "testprogcgo", "CgoCallbackGC") want := "OK\n" if got != want { - t.Fatalf("expected %q, but got %q", want, got) + t.Fatalf("expected %q, but got:\n%s", want, got) } } @@ -54,11 +59,7 @@ func TestCgoExternalThreadPanic(t *testing.T) { if runtime.GOOS == "plan9" { t.Skipf("no pthreads on %s", runtime.GOOS) } - csrc := cgoExternalThreadPanicC - if runtime.GOOS == "windows" { - csrc = cgoExternalThreadPanicC_windows - } - got := executeTest(t, cgoExternalThreadPanicSource, nil, "main.c", csrc) + got := runTestProg(t, "testprogcgo", "CgoExternalThreadPanic") want := "panic: BOOM" if !strings.Contains(got, want) { t.Fatalf("want failure containing %q. output:\n%s\n", want, got) @@ -84,15 +85,15 @@ func TestCgoExternalThreadSIGPROF(t *testing.T) { } } } - if runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" { + if runtime.GOARCH == "ppc64" { // TODO(austin) External linking not implemented on // ppc64 (issue #8912) t.Skipf("no external linking on ppc64") } - got := executeTest(t, cgoExternalThreadSIGPROFSource, nil) + got := runTestProg(t, "testprogcgo", "CgoExternalThreadSIGPROF") want := "OK\n" if got != want { - t.Fatalf("expected %q, but got %q", want, got) + t.Fatalf("expected %q, but got:\n%s", want, got) } } @@ -102,10 +103,10 @@ func TestCgoExternalThreadSignal(t *testing.T) { case "plan9", "windows": t.Skipf("no pthreads on %s", runtime.GOOS) } - got := executeTest(t, cgoExternalThreadSignalSource, nil) + got := runTestProg(t, "testprogcgo", "CgoExternalThreadSignal") want := "OK\n" if got != want { - t.Fatalf("expected %q, but got %q", want, got) + t.Fatalf("expected %q, but got:\n%s", want, got) } } @@ -114,368 +115,35 @@ func TestCgoDLLImports(t *testing.T) { if runtime.GOOS != "windows" { t.Skip("skipping windows specific test") } - got := executeTest(t, cgoDLLImportsMainSource, nil, "a/a.go", cgoDLLImportsPkgSource) + got := runTestProg(t, "testprogcgo", "CgoDLLImportsMain") want := "OK\n" if got != want { t.Fatalf("expected %q, but got %v", want, got) } } -const cgoSignalDeadlockSource = ` -package main - -import "C" - -import ( - "fmt" - "runtime" - "time" -) - -func main() { - runtime.GOMAXPROCS(100) - ping := make(chan bool) - go func() { - for i := 0; ; i++ { - runtime.Gosched() - select { - case done := <-ping: - if done { - ping <- true - return - } - ping <- true - default: - } - func() { - defer func() { - recover() - }() - var s *string - *s = "" - }() - } - }() - time.Sleep(time.Millisecond) - for i := 0; i < 64; i++ { - go func() { - runtime.LockOSThread() - select {} - }() - go func() { - runtime.LockOSThread() - select {} - }() - time.Sleep(time.Millisecond) - ping <- false - select { - case <-ping: - case <-time.After(time.Second): - fmt.Printf("HANG\n") - return - } - } - ping <- true - select { - case <-ping: - case <-time.After(time.Second): - fmt.Printf("HANG\n") - return - } - fmt.Printf("OK\n") -} -` - -const cgoTracebackSource = ` -package main - -/* void foo(void) {} */ -import "C" - -import ( - "fmt" - "runtime" -) - -func main() { - C.foo() - buf := make([]byte, 1) - runtime.Stack(buf, true) - fmt.Printf("OK\n") -} -` - -const cgoCallbackGCSource = ` -package main - -import "runtime" - -/* -#include <pthread.h> - -void go_callback(); - -static void *thr(void *arg) { - go_callback(); - return 0; -} - -static void foo() { - pthread_t th; - pthread_create(&th, 0, thr, 0); - pthread_join(th, 0); -} -*/ -import "C" -import "fmt" - -//export go_callback -func go_callback() { - runtime.GC() - grow() - runtime.GC() -} - -var cnt int - -func grow() { - x := 10000 - sum := 0 - if grow1(&x, &sum) == 0 { - panic("bad") - } -} - -func grow1(x, sum *int) int { - if *x == 0 { - return *sum + 1 - } - *x-- - sum1 := *sum + *x - return grow1(x, &sum1) -} - -func main() { - const P = 100 - done := make(chan bool) - // allocate a bunch of stack frames and spray them with pointers - for i := 0; i < P; i++ { - go func() { - grow() - done <- true - }() - } - for i := 0; i < P; i++ { - <-done - } - // now give these stack frames to cgo callbacks - for i := 0; i < P; i++ { - go func() { - C.foo() - done <- true - }() - } - for i := 0; i < P; i++ { - <-done +func TestCgoExecSignalMask(t *testing.T) { + // Test issue 13164. + switch runtime.GOOS { + case "windows", "plan9": + t.Skipf("skipping signal mask test on %s", runtime.GOOS) } - fmt.Printf("OK\n") -} -` - -const cgoExternalThreadPanicSource = ` -package main - -// void start(void); -import "C" - -func main() { - C.start() - select {} -} - -//export gopanic -func gopanic() { - panic("BOOM") -} -` - -const cgoExternalThreadPanicC = ` -#include <stdlib.h> -#include <stdio.h> -#include <pthread.h> - -void gopanic(void); - -static void* -die(void* x) -{ - gopanic(); - return 0; -} - -void -start(void) -{ - pthread_t t; - if(pthread_create(&t, 0, die, 0) != 0) - printf("pthread_create failed\n"); -} -` - -const cgoExternalThreadPanicC_windows = ` -#include <stdlib.h> -#include <stdio.h> - -void gopanic(void); - -static void* -die(void* x) -{ - gopanic(); - return 0; -} - -void -start(void) -{ - if(_beginthreadex(0, 0, die, 0, 0, 0) != 0) - printf("_beginthreadex failed\n"); -} -` - -const cgoExternalThreadSIGPROFSource = ` -package main - -/* -#include <stdint.h> -#include <signal.h> -#include <pthread.h> - -volatile int32_t spinlock; - -static void *thread1(void *p) { - (void)p; - while (spinlock == 0) - ; - pthread_kill(pthread_self(), SIGPROF); - spinlock = 0; - return NULL; -} -__attribute__((constructor)) void issue9456() { - pthread_t tid; - pthread_create(&tid, 0, thread1, NULL); -} -*/ -import "C" - -import ( - "runtime" - "sync/atomic" - "unsafe" -) - -func main() { - // This test intends to test that sending SIGPROF to foreign threads - // before we make any cgo call will not abort the whole process, so - // we cannot make any cgo call here. See https://golang.org/issue/9456. - atomic.StoreInt32((*int32)(unsafe.Pointer(&C.spinlock)), 1) - for atomic.LoadInt32((*int32)(unsafe.Pointer(&C.spinlock))) == 1 { - runtime.Gosched() + got := runTestProg(t, "testprogcgo", "CgoExecSignalMask") + want := "OK\n" + if got != want { + t.Errorf("expected %q, got %v", want, got) } - println("OK") -} -` - -const cgoExternalThreadSignalSource = ` -package main - -/* -#include <pthread.h> - -void **nullptr; - -void *crash(void *p) { - *nullptr = p; - return 0; } -int start_crashing_thread(void) { - pthread_t tid; - return pthread_create(&tid, 0, crash, 0); -} -*/ -import "C" - -import ( - "fmt" - "os" - "os/exec" - "time" -) - -func main() { - if len(os.Args) > 1 && os.Args[1] == "crash" { - i := C.start_crashing_thread() - if i != 0 { - fmt.Println("pthread_create failed:", i) - // Exit with 0 because parent expects us to crash. - return - } - - // We should crash immediately, but give it plenty of - // time before failing (by exiting 0) in case we are - // running on a slow system. - time.Sleep(5 * time.Second) - return +func TestEnsureDropM(t *testing.T) { + // Test for issue 13881. + switch runtime.GOOS { + case "windows", "plan9": + t.Skipf("skipping dropm test on %s", runtime.GOOS) } - - out, err := exec.Command(os.Args[0], "crash").CombinedOutput() - if err == nil { - fmt.Println("C signal did not crash as expected\n") - fmt.Printf("%s\n", out) - os.Exit(1) + got := runTestProg(t, "testprogcgo", "EnsureDropM") + want := "OK\n" + if got != want { + t.Errorf("expected %q, got %v", want, got) } - - fmt.Println("OK") -} -` - -const cgoDLLImportsMainSource = ` -package main - -/* -#include <windows.h> - -DWORD getthread() { - return GetCurrentThreadId(); -} -*/ -import "C" - -import "./a" - -func main() { - C.getthread() - a.GetThread() - println("OK") -} -` - -const cgoDLLImportsPkgSource = ` -package a - -/* -#cgo CFLAGS: -mnop-fun-dllimport - -#include <windows.h> - -DWORD agetthread() { - return GetCurrentThreadId(); -} -*/ -import "C" - -func GetThread() uint32 { - return uint32(C.agetthread()) } -` |