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.
22 func TestCgoCrashHandler(t
*testing
.T
) {
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")
38 t
.Fatalf("expected %q, but got:\n%s", want
, got
)
42 func TestCgoTraceback(t
*testing
.T
) {
44 got
:= runTestProg(t
, "testprogcgo", "CgoTraceback")
47 t
.Fatalf("expected %q, but got:\n%s", want
, got
)
51 func TestCgoCallbackGC(t
*testing
.T
) {
54 case "plan9", "windows":
55 t
.Skipf("no pthreads on %s", runtime
.GOOS
)
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")
70 t
.Fatalf("expected %q, but got:\n%s", want
, got
)
74 func TestCgoExternalThreadPanic(t
*testing
.T
) {
76 if runtime
.GOOS
== "plan9" {
77 t
.Skipf("no pthreads on %s", runtime
.GOOS
)
79 got
:= runTestProg(t
, "testprogcgo", "CgoExternalThreadPanic")
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
) {
90 case "plan9", "windows":
91 t
.Skipf("no pthreads on %s", runtime
.GOOS
)
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()
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")
117 got
, err
:= testenv
.CleanCmdEnv(exec
.Command(exe
, "CgoExternalThreadSIGPROF")).CombinedOutput()
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
) {
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")
140 got
, err
:= testenv
.CleanCmdEnv(exec
.Command(exe
, "CgoExternalThreadSIGPROF")).CombinedOutput()
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
) {
153 if runtime
.GOOS
!= "windows" {
154 t
.Skip("skipping windows specific test")
156 got
:= runTestProg(t
, "testprogcgo", "CgoDLLImportsMain")
159 t
.Fatalf("expected %q, but got %v", want
, got
)
163 func TestCgoExecSignalMask(t
*testing
.T
) {
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")
173 t
.Errorf("expected %q, got %v", want
, got
)
177 func TestEnsureDropM(t
*testing
.T
) {
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")
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
) {
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")
203 // Try it 10 times to avoid flakiness.
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
))
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
))
219 d2
:= time
.Since(start
)
222 // The slow version (d2) was less than 20 times
223 // slower than the fast version (d1), so OK.
231 t
.Errorf("cgo check too slow: got %v, expected at most %v", tot2
/tries
, (tot1
/tries
)*20)
234 func TestCgoPanicDeadlock(t
*testing
.T
) {
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
) {
246 got
:= runTestProg(t
, "testprogcgo", "CgoCCodeSIGPROF")
249 t
.Errorf("expected %q got %v", want
, got
)
253 func TestCgoCrashTraceback(t
*testing
.T
) {
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
) {
271 if runtime
.Compiler
== "gccgo" {
272 t
.Skip("gccgo does not have SetCgoTraceback")
274 got
:= runTestProg(t
, "testprogcgo", "TracebackContext")
277 t
.Errorf("expected %q got %v", want
, got
)
281 func testCgoPprof(t
*testing
.T
, buildArg
, runArg
string) {
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
)
296 got
, err
:= testenv
.CleanCmdEnv(exec
.Command(exe
, runArg
)).CombinedOutput()
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
)
304 fn
:= strings
.TrimSpace(string(got
))
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.
311 cmd
.Args
= append(cmd
.Args
, exe
, fn
)
313 cmd
.Args
= append(cmd
.Args
, fn
)
317 for i
, e
:= range cmd
.Env
{
318 if strings
.HasPrefix(e
, "PPROF_TMPDIR=") {
319 cmd
.Env
[i
] = "PPROF_TMPDIR=" + os
.TempDir()
325 cmd
.Env
= append(cmd
.Env
, "PPROF_TMPDIR="+os
.TempDir())
328 top
, err
:= cmd
.CombinedOutput()
329 t
.Logf("%s:\n%s", cmd
.Args
, top
)
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.
367 t
.Skip("skipping test in -short mode")
370 exe
, err
:= buildTestProg(t
, "testprogcgo", "-race")
375 got
, err
:= testenv
.CleanCmdEnv(exec
.Command(exe
, "CgoRaceprof")).CombinedOutput()
380 if string(got
) != want
{
381 t
.Errorf("expected %q got %s", want
, got
)
385 func TestRaceSignal(t
*testing
.T
) {
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.
396 t
.Skip("skipping test in -short mode")
399 exe
, err
:= buildTestProg(t
, "testprogcgo", "-race")
404 got
, err
:= testenv
.CleanCmdEnv(exec
.Command(exe
, "CgoRaceSignal")).CombinedOutput()
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
)
421 got
:= runTestProg(t
, "testprogcgo", "NumGoroutine")
424 t
.Errorf("expected %q got %v", want
, got
)
428 func TestCatchPanic(t
*testing
.T
) {
430 switch runtime
.GOOS
{
431 case "plan9", "windows":
432 t
.Skipf("no signals on %s", runtime
.GOOS
)
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")
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")
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
)
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
)
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
)
490 got
:= runTestProg(t
, "testprogcgo", "SigStack")
493 t
.Errorf("expected %q got %v", want
, got
)