Alex Brainman | afe0e97 | 2012-05-30 15:10:54 +1000 | [diff] [blame] | 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 | // +build cgo |
| 6 | |
| 7 | package runtime_test |
| 8 | |
| 9 | import ( |
Ian Lance Taylor | 84e8080 | 2016-04-29 15:20:27 -0700 | [diff] [blame] | 10 | "bytes" |
Ian Lance Taylor | 8d94b9b | 2016-02-25 21:16:45 -0800 | [diff] [blame] | 11 | "fmt" |
Ian Lance Taylor | c8e7b34 | 2016-02-18 11:04:05 -0800 | [diff] [blame] | 12 | "internal/testenv" |
Mohit Agarwal | 4d6788e | 2016-05-05 00:04:54 +0530 | [diff] [blame] | 13 | "os" |
Shenghou Ma | 865e5e9 | 2015-01-03 00:12:34 -0500 | [diff] [blame] | 14 | "os/exec" |
Dmitriy Vyukov | 1590abe | 2013-08-08 00:04:28 +0400 | [diff] [blame] | 15 | "runtime" |
Russ Cox | c4efaac | 2014-10-28 21:53:09 -0400 | [diff] [blame] | 16 | "strings" |
Alex Brainman | afe0e97 | 2012-05-30 15:10:54 +1000 | [diff] [blame] | 17 | "testing" |
Ian Lance Taylor | c8e7b34 | 2016-02-18 11:04:05 -0800 | [diff] [blame] | 18 | "time" |
Alex Brainman | afe0e97 | 2012-05-30 15:10:54 +1000 | [diff] [blame] | 19 | ) |
| 20 | |
| 21 | func TestCgoCrashHandler(t *testing.T) { |
Dmitriy Vyukov | 06a488f | 2013-02-20 12:15:02 +0400 | [diff] [blame] | 22 | testCrashHandler(t, true) |
Alex Brainman | afe0e97 | 2012-05-30 15:10:54 +1000 | [diff] [blame] | 23 | } |
Shenghou Ma | 6ecb39f | 2013-02-28 16:07:26 +0800 | [diff] [blame] | 24 | |
| 25 | func TestCgoSignalDeadlock(t *testing.T) { |
Dmitriy Vyukov | 1590abe | 2013-08-08 00:04:28 +0400 | [diff] [blame] | 26 | if testing.Short() && runtime.GOOS == "windows" { |
| 27 | t.Skip("Skipping in short mode") // takes up to 64 seconds |
| 28 | } |
Russ Cox | 8d5ff2e | 2015-12-21 10:29:21 -0500 | [diff] [blame] | 29 | got := runTestProg(t, "testprogcgo", "CgoSignalDeadlock") |
Shenghou Ma | 6ecb39f | 2013-02-28 16:07:26 +0800 | [diff] [blame] | 30 | want := "OK\n" |
| 31 | if got != want { |
Russ Cox | 8d5ff2e | 2015-12-21 10:29:21 -0500 | [diff] [blame] | 32 | t.Fatalf("expected %q, but got:\n%s", want, got) |
Shenghou Ma | 6ecb39f | 2013-02-28 16:07:26 +0800 | [diff] [blame] | 33 | } |
| 34 | } |
| 35 | |
Dmitriy Vyukov | 326ae8d | 2013-08-08 00:31:52 +0400 | [diff] [blame] | 36 | func TestCgoTraceback(t *testing.T) { |
Russ Cox | 8d5ff2e | 2015-12-21 10:29:21 -0500 | [diff] [blame] | 37 | got := runTestProg(t, "testprogcgo", "CgoTraceback") |
Dmitriy Vyukov | 326ae8d | 2013-08-08 00:31:52 +0400 | [diff] [blame] | 38 | want := "OK\n" |
| 39 | if got != want { |
Russ Cox | 8d5ff2e | 2015-12-21 10:29:21 -0500 | [diff] [blame] | 40 | t.Fatalf("expected %q, but got:\n%s", want, got) |
Dmitriy Vyukov | 326ae8d | 2013-08-08 00:31:52 +0400 | [diff] [blame] | 41 | } |
| 42 | } |
| 43 | |
Russ Cox | fde3926 | 2015-07-29 16:16:13 -0400 | [diff] [blame] | 44 | func TestCgoCallbackGC(t *testing.T) { |
| 45 | if runtime.GOOS == "plan9" || runtime.GOOS == "windows" { |
| 46 | t.Skipf("no pthreads on %s", runtime.GOOS) |
| 47 | } |
Dave Cheney | 9840042 | 2015-09-11 10:15:17 +1000 | [diff] [blame] | 48 | if testing.Short() { |
| 49 | switch { |
| 50 | case runtime.GOOS == "dragonfly": |
| 51 | t.Skip("see golang.org/issue/11990") |
| 52 | case runtime.GOOS == "linux" && runtime.GOARCH == "arm": |
| 53 | t.Skip("too slow for arm builders") |
Cherry Zhang | bcd4b84 | 2016-05-04 22:07:50 -0700 | [diff] [blame] | 54 | case runtime.GOOS == "linux" && (runtime.GOARCH == "mips64" || runtime.GOARCH == "mips64le"): |
| 55 | t.Skip("too slow for mips64x builders") |
Dave Cheney | 9840042 | 2015-09-11 10:15:17 +1000 | [diff] [blame] | 56 | } |
Mikio Hara | 5e15e28 | 2015-08-03 12:43:25 +0900 | [diff] [blame] | 57 | } |
Russ Cox | 8d5ff2e | 2015-12-21 10:29:21 -0500 | [diff] [blame] | 58 | got := runTestProg(t, "testprogcgo", "CgoCallbackGC") |
Russ Cox | fde3926 | 2015-07-29 16:16:13 -0400 | [diff] [blame] | 59 | want := "OK\n" |
| 60 | if got != want { |
Russ Cox | 8d5ff2e | 2015-12-21 10:29:21 -0500 | [diff] [blame] | 61 | t.Fatalf("expected %q, but got:\n%s", want, got) |
Russ Cox | fde3926 | 2015-07-29 16:16:13 -0400 | [diff] [blame] | 62 | } |
| 63 | } |
| 64 | |
Russ Cox | c4efaac | 2014-10-28 21:53:09 -0400 | [diff] [blame] | 65 | func TestCgoExternalThreadPanic(t *testing.T) { |
Alex Brainman | f9c4c16 | 2014-10-30 10:24:37 +1100 | [diff] [blame] | 66 | if runtime.GOOS == "plan9" { |
Russ Cox | 3ce6a4f | 2014-10-29 00:02:29 -0400 | [diff] [blame] | 67 | t.Skipf("no pthreads on %s", runtime.GOOS) |
| 68 | } |
Russ Cox | 8d5ff2e | 2015-12-21 10:29:21 -0500 | [diff] [blame] | 69 | got := runTestProg(t, "testprogcgo", "CgoExternalThreadPanic") |
Russ Cox | c4efaac | 2014-10-28 21:53:09 -0400 | [diff] [blame] | 70 | want := "panic: BOOM" |
| 71 | if !strings.Contains(got, want) { |
| 72 | t.Fatalf("want failure containing %q. output:\n%s\n", want, got) |
| 73 | } |
| 74 | } |
| 75 | |
Shenghou Ma | 5da9c8c | 2014-12-27 19:15:38 -0500 | [diff] [blame] | 76 | func TestCgoExternalThreadSIGPROF(t *testing.T) { |
| 77 | // issue 9456. |
Shenghou Ma | 2cbe27a | 2015-01-01 01:10:39 -0500 | [diff] [blame] | 78 | switch runtime.GOOS { |
| 79 | case "plan9", "windows": |
Shenghou Ma | 5da9c8c | 2014-12-27 19:15:38 -0500 | [diff] [blame] | 80 | t.Skipf("no pthreads on %s", runtime.GOOS) |
Shenghou Ma | 2cbe27a | 2015-01-01 01:10:39 -0500 | [diff] [blame] | 81 | case "darwin": |
David Crawshaw | d6d423b | 2015-04-11 19:00:53 -0400 | [diff] [blame] | 82 | if runtime.GOARCH != "arm" && runtime.GOARCH != "arm64" { |
David Crawshaw | 95bf77b | 2015-02-26 18:05:47 -0500 | [diff] [blame] | 83 | // static constructor needs external linking, but we don't support |
| 84 | // external linking on OS X 10.6. |
| 85 | out, err := exec.Command("uname", "-r").Output() |
| 86 | if err != nil { |
| 87 | t.Fatalf("uname -r failed: %v", err) |
| 88 | } |
| 89 | // OS X 10.6 == Darwin 10.x |
| 90 | if strings.HasPrefix(string(out), "10.") { |
| 91 | t.Skipf("no external linking on OS X 10.6") |
| 92 | } |
Shenghou Ma | 2cbe27a | 2015-01-01 01:10:39 -0500 | [diff] [blame] | 93 | } |
Shenghou Ma | 5da9c8c | 2014-12-27 19:15:38 -0500 | [diff] [blame] | 94 | } |
Michael Hudson-Doyle | 58db5fc | 2015-11-12 13:05:49 +1300 | [diff] [blame] | 95 | if runtime.GOARCH == "ppc64" { |
Austin Clements | af7ca8d | 2014-12-16 18:34:55 -0500 | [diff] [blame] | 96 | // TODO(austin) External linking not implemented on |
| 97 | // ppc64 (issue #8912) |
| 98 | t.Skipf("no external linking on ppc64") |
| 99 | } |
Russ Cox | 8d5ff2e | 2015-12-21 10:29:21 -0500 | [diff] [blame] | 100 | got := runTestProg(t, "testprogcgo", "CgoExternalThreadSIGPROF") |
Shenghou Ma | 5da9c8c | 2014-12-27 19:15:38 -0500 | [diff] [blame] | 101 | want := "OK\n" |
| 102 | if got != want { |
Russ Cox | 8d5ff2e | 2015-12-21 10:29:21 -0500 | [diff] [blame] | 103 | t.Fatalf("expected %q, but got:\n%s", want, got) |
Shenghou Ma | 5da9c8c | 2014-12-27 19:15:38 -0500 | [diff] [blame] | 104 | } |
| 105 | } |
| 106 | |
Ian Lance Taylor | 872b168 | 2015-07-21 22:34:48 -0700 | [diff] [blame] | 107 | func TestCgoExternalThreadSignal(t *testing.T) { |
| 108 | // issue 10139 |
| 109 | switch runtime.GOOS { |
| 110 | case "plan9", "windows": |
| 111 | t.Skipf("no pthreads on %s", runtime.GOOS) |
| 112 | } |
Russ Cox | 8d5ff2e | 2015-12-21 10:29:21 -0500 | [diff] [blame] | 113 | got := runTestProg(t, "testprogcgo", "CgoExternalThreadSignal") |
Ian Lance Taylor | 872b168 | 2015-07-21 22:34:48 -0700 | [diff] [blame] | 114 | want := "OK\n" |
| 115 | if got != want { |
Russ Cox | 8d5ff2e | 2015-12-21 10:29:21 -0500 | [diff] [blame] | 116 | t.Fatalf("expected %q, but got:\n%s", want, got) |
Ian Lance Taylor | 872b168 | 2015-07-21 22:34:48 -0700 | [diff] [blame] | 117 | } |
| 118 | } |
| 119 | |
Alex Brainman | 9b69196 | 2015-03-16 15:46:22 +1100 | [diff] [blame] | 120 | func TestCgoDLLImports(t *testing.T) { |
| 121 | // test issue 9356 |
| 122 | if runtime.GOOS != "windows" { |
| 123 | t.Skip("skipping windows specific test") |
| 124 | } |
Russ Cox | 8d5ff2e | 2015-12-21 10:29:21 -0500 | [diff] [blame] | 125 | got := runTestProg(t, "testprogcgo", "CgoDLLImportsMain") |
Alex Brainman | 9b69196 | 2015-03-16 15:46:22 +1100 | [diff] [blame] | 126 | want := "OK\n" |
| 127 | if got != want { |
| 128 | t.Fatalf("expected %q, but got %v", want, got) |
| 129 | } |
| 130 | } |
Ian Lance Taylor | 70c9a81 | 2015-12-19 10:17:10 -0800 | [diff] [blame] | 131 | |
| 132 | func TestCgoExecSignalMask(t *testing.T) { |
| 133 | // Test issue 13164. |
| 134 | switch runtime.GOOS { |
| 135 | case "windows", "plan9": |
| 136 | t.Skipf("skipping signal mask test on %s", runtime.GOOS) |
| 137 | } |
| 138 | got := runTestProg(t, "testprogcgo", "CgoExecSignalMask") |
| 139 | want := "OK\n" |
| 140 | if got != want { |
| 141 | t.Errorf("expected %q, got %v", want, got) |
| 142 | } |
| 143 | } |
Ian Lance Taylor | c02aa46 | 2016-01-08 16:56:02 -0800 | [diff] [blame] | 144 | |
| 145 | func TestEnsureDropM(t *testing.T) { |
| 146 | // Test for issue 13881. |
Ian Lance Taylor | 9270973 | 2016-01-18 09:01:48 -0800 | [diff] [blame] | 147 | switch runtime.GOOS { |
| 148 | case "windows", "plan9": |
| 149 | t.Skipf("skipping dropm test on %s", runtime.GOOS) |
| 150 | } |
Ian Lance Taylor | c02aa46 | 2016-01-08 16:56:02 -0800 | [diff] [blame] | 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 | } |
Ian Lance Taylor | c8e7b34 | 2016-02-18 11:04:05 -0800 | [diff] [blame] | 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 | // Make sure we don't count the build time as part of the run time. |
| 163 | testenv.MustHaveGoBuild(t) |
| 164 | exe, err := buildTestProg(t, "testprogcgo") |
| 165 | if err != nil { |
| 166 | t.Fatal(err) |
| 167 | } |
| 168 | |
Ian Lance Taylor | 8d94b9b | 2016-02-25 21:16:45 -0800 | [diff] [blame] | 169 | // Try it 10 times to avoid flakiness. |
| 170 | const tries = 10 |
| 171 | var tot1, tot2 time.Duration |
| 172 | for i := 0; i < tries; i++ { |
| 173 | cmd := testEnv(exec.Command(exe, "CgoCheckBytes")) |
| 174 | cmd.Env = append(cmd.Env, "GODEBUG=cgocheck=0", fmt.Sprintf("GO_CGOCHECKBYTES_TRY=%d", i)) |
Ian Lance Taylor | c8e7b34 | 2016-02-18 11:04:05 -0800 | [diff] [blame] | 175 | |
Ian Lance Taylor | 8d94b9b | 2016-02-25 21:16:45 -0800 | [diff] [blame] | 176 | start := time.Now() |
| 177 | cmd.Run() |
| 178 | d1 := time.Since(start) |
Ian Lance Taylor | c8e7b34 | 2016-02-18 11:04:05 -0800 | [diff] [blame] | 179 | |
Ian Lance Taylor | 8d94b9b | 2016-02-25 21:16:45 -0800 | [diff] [blame] | 180 | cmd = testEnv(exec.Command(exe, "CgoCheckBytes")) |
| 181 | cmd.Env = append(cmd.Env, fmt.Sprintf("GO_CGOCHECKBYTES_TRY=%d", i)) |
Ian Lance Taylor | c8e7b34 | 2016-02-18 11:04:05 -0800 | [diff] [blame] | 182 | |
Ian Lance Taylor | 8d94b9b | 2016-02-25 21:16:45 -0800 | [diff] [blame] | 183 | start = time.Now() |
| 184 | cmd.Run() |
| 185 | d2 := time.Since(start) |
Ian Lance Taylor | c8e7b34 | 2016-02-18 11:04:05 -0800 | [diff] [blame] | 186 | |
Ian Lance Taylor | 8d94b9b | 2016-02-25 21:16:45 -0800 | [diff] [blame] | 187 | if d1*20 > d2 { |
| 188 | // The slow version (d2) was less than 20 times |
| 189 | // slower than the fast version (d1), so OK. |
| 190 | return |
| 191 | } |
| 192 | |
| 193 | tot1 += d1 |
| 194 | tot2 += d2 |
Ian Lance Taylor | c8e7b34 | 2016-02-18 11:04:05 -0800 | [diff] [blame] | 195 | } |
Ian Lance Taylor | 8d94b9b | 2016-02-25 21:16:45 -0800 | [diff] [blame] | 196 | |
| 197 | t.Errorf("cgo check too slow: got %v, expected at most %v", tot2/tries, (tot1/tries)*20) |
Ian Lance Taylor | c8e7b34 | 2016-02-18 11:04:05 -0800 | [diff] [blame] | 198 | } |
Shenghou Ma | e960302 | 2016-02-21 13:56:08 -0500 | [diff] [blame] | 199 | |
| 200 | func TestCgoPanicDeadlock(t *testing.T) { |
| 201 | // test issue 14432 |
| 202 | got := runTestProg(t, "testprogcgo", "CgoPanicDeadlock") |
| 203 | want := "panic: cgo error\n\n" |
| 204 | if !strings.HasPrefix(got, want) { |
| 205 | t.Fatalf("output does not start with %q:\n%s", want, got) |
| 206 | } |
| 207 | } |
Ian Lance Taylor | 1716162 | 2016-03-04 11:29:55 -0800 | [diff] [blame] | 208 | |
| 209 | func TestCgoCCodeSIGPROF(t *testing.T) { |
| 210 | got := runTestProg(t, "testprogcgo", "CgoCCodeSIGPROF") |
| 211 | want := "OK\n" |
| 212 | if got != want { |
| 213 | t.Errorf("expected %q got %v", want, got) |
| 214 | } |
| 215 | } |
Ian Lance Taylor | ea306ae | 2015-12-11 17:16:48 -0800 | [diff] [blame] | 216 | |
| 217 | func TestCgoCrashTraceback(t *testing.T) { |
| 218 | if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { |
| 219 | t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH) |
| 220 | } |
| 221 | got := runTestProg(t, "testprogcgo", "CrashTraceback") |
| 222 | for i := 1; i <= 3; i++ { |
| 223 | if !strings.Contains(got, fmt.Sprintf("cgo symbolizer:%d", i)) { |
| 224 | t.Errorf("missing cgo symbolizer:%d", i) |
| 225 | } |
| 226 | } |
| 227 | } |
Ian Lance Taylor | 5f9a870 | 2016-04-27 14:18:29 -0700 | [diff] [blame] | 228 | |
| 229 | func TestCgoTracebackContext(t *testing.T) { |
Ian Lance Taylor | 5f9a870 | 2016-04-27 14:18:29 -0700 | [diff] [blame] | 230 | got := runTestProg(t, "testprogcgo", "TracebackContext") |
| 231 | want := "OK\n" |
| 232 | if got != want { |
| 233 | t.Errorf("expected %q got %v", want, got) |
| 234 | } |
| 235 | } |
Ian Lance Taylor | 84e8080 | 2016-04-29 15:20:27 -0700 | [diff] [blame] | 236 | |
| 237 | func TestCgoPprof(t *testing.T) { |
| 238 | if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { |
| 239 | t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH) |
| 240 | } |
| 241 | testenv.MustHaveGoRun(t) |
| 242 | |
| 243 | exe, err := buildTestProg(t, "testprogcgo") |
| 244 | if err != nil { |
| 245 | t.Fatal(err) |
| 246 | } |
| 247 | |
| 248 | got, err := testEnv(exec.Command(exe, "CgoPprof")).CombinedOutput() |
| 249 | if err != nil { |
| 250 | t.Fatal(err) |
| 251 | } |
| 252 | fn := strings.TrimSpace(string(got)) |
Mohit Agarwal | 4d6788e | 2016-05-05 00:04:54 +0530 | [diff] [blame] | 253 | defer os.Remove(fn) |
Ian Lance Taylor | 84e8080 | 2016-04-29 15:20:27 -0700 | [diff] [blame] | 254 | |
| 255 | top, err := exec.Command("go", "tool", "pprof", "-top", "-nodecount=1", exe, fn).CombinedOutput() |
| 256 | if err != nil { |
| 257 | t.Fatal(err) |
| 258 | } |
| 259 | |
| 260 | t.Logf("%s", top) |
| 261 | |
| 262 | if !bytes.Contains(top, []byte("cpuHog")) { |
| 263 | t.Error("missing cpuHog in pprof output") |
| 264 | } |
| 265 | } |
Ian Lance Taylor | 4223294 | 2016-05-27 16:03:44 -0700 | [diff] [blame^] | 266 | |
| 267 | func TestCgoPprofPIE(t *testing.T) { |
| 268 | if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { |
| 269 | t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH) |
| 270 | } |
| 271 | testenv.MustHaveGoRun(t) |
| 272 | |
| 273 | exe, err := buildTestProg(t, "testprogcgo", "-ldflags=-extldflags=-pie") |
| 274 | if err != nil { |
| 275 | t.Fatal(err) |
| 276 | } |
| 277 | |
| 278 | got, err := testEnv(exec.Command(exe, "CgoPprof")).CombinedOutput() |
| 279 | if err != nil { |
| 280 | t.Fatal(err) |
| 281 | } |
| 282 | fn := strings.TrimSpace(string(got)) |
| 283 | defer os.Remove(fn) |
| 284 | |
| 285 | top, err := exec.Command("go", "tool", "pprof", "-top", "-nodecount=1", exe, fn).CombinedOutput() |
| 286 | if err != nil { |
| 287 | t.Fatal(err) |
| 288 | } |
| 289 | |
| 290 | t.Logf("%s", top) |
| 291 | |
| 292 | if !bytes.Contains(top, []byte("cpuHog")) { |
| 293 | t.Error("missing cpuHog in pprof output") |
| 294 | } |
| 295 | } |