Source file
misc/cgo/test/testx.go
1
2
3
4
5
6
7
8
9
10
11 package cgotest
12
13 import (
14 "runtime"
15 "runtime/cgo"
16 "runtime/debug"
17 "strings"
18 "sync"
19 "sync/atomic"
20 "testing"
21 "time"
22 "unsafe"
23 )
24
25
118 import "C"
119
120
121
122
123 func ReturnIntLong() (int, C.long) {
124 return 1, 2
125 }
126
127
128 func gc() {
129 runtime.GC()
130 }
131
132
133
134 var sum struct {
135 sync.Mutex
136 i int
137 }
138
139
140 func Add(x int) {
141 defer func() {
142 recover()
143 }()
144 sum.Lock()
145 sum.i += x
146 sum.Unlock()
147 var p *int
148 *p = 2
149 }
150
151 func testCthread(t *testing.T) {
152 if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && runtime.GOARCH == "arm64" {
153 t.Skip("the iOS exec wrapper is unable to properly handle the panic from Add")
154 }
155 sum.i = 0
156 C.doAdd(10, 6)
157
158 want := 10 * (10 - 1) / 2 * 6
159 if sum.i != want {
160 t.Fatalf("sum=%d, want %d", sum.i, want)
161 }
162 }
163
164
165
166
167 func BackIntoGo() {
168 x := 1
169
170 for i := 0; i < 10000; i++ {
171 xvariadic(x)
172 if x != 1 {
173 panic("x is not 1?")
174 }
175 }
176 }
177
178 func xvariadic(x ...interface{}) {
179 }
180
181 func test1328(t *testing.T) {
182 C.IntoC()
183 }
184
185
186
187 var sleepDone = make(chan int64)
188
189
190
191 func parallelSleep(n int) int64 {
192 t := int64(C.twoSleep(C.int(n))) - <-sleepDone
193 if t < 0 {
194 return -t
195 }
196 return t
197 }
198
199
200 func BackgroundSleep(n int32) {
201 go func() {
202 sleepDone <- int64(C.mysleep(C.int(n)))
203 }()
204 }
205
206 func testParallelSleep(t *testing.T) {
207 sleepSec := 1
208 dt := time.Duration(parallelSleep(sleepSec)) * time.Millisecond
209 t.Logf("difference in start time for two sleep(%d) is %v", sleepSec, dt)
210
211
212 if dt >= time.Duration(sleepSec)*time.Second/2 {
213 t.Fatalf("parallel %d-second sleeps slept for %f seconds", sleepSec, dt.Seconds())
214 }
215 }
216
217
218
219
220 func exportbyte() byte {
221 return 0
222 }
223
224
225 func exportbool() bool {
226 return false
227 }
228
229
230 func exportrune() rune {
231 return 0
232 }
233
234
235 func exporterror() error {
236 return nil
237 }
238
239
240 func exportint() int {
241 return 0
242 }
243
244
245 func exportuint() uint {
246 return 0
247 }
248
249
250 func exportuintptr() uintptr {
251 return (uintptr)(0)
252 }
253
254
255 func exportint8() int8 {
256 return 0
257 }
258
259
260 func exportuint8() uint8 {
261 return 0
262 }
263
264
265 func exportint16() int16 {
266 return 0
267 }
268
269
270 func exportuint16() uint16 {
271 return 0
272 }
273
274
275 func exportint32() int32 {
276 return 0
277 }
278
279
280 func exportuint32() uint32 {
281 return 0
282 }
283
284
285 func exportint64() int64 {
286 return 0
287 }
288
289
290 func exportuint64() uint64 {
291 return 0
292 }
293
294
295 func exportfloat32() float32 {
296 return 0
297 }
298
299
300 func exportfloat64() float64 {
301 return 0
302 }
303
304
305 func exportcomplex64() complex64 {
306 return 0
307 }
308
309
310 func exportcomplex128() complex128 {
311 return 0
312 }
313
314
315
316
317 func exportSliceIn(s []byte) bool {
318 return len(s) == cap(s)
319 }
320
321
322 func exportSliceOut() []byte {
323 return []byte{1}
324 }
325
326
327 func exportSliceInOut(s []byte) []byte {
328 return s
329 }
330
331
332
333 func init() {
334 if runtime.GOOS == "android" {
335 return
336 }
337
338
339
340
341 C.lockOSThreadC()
342 }
343
344 func test3775(t *testing.T) {
345 if runtime.GOOS == "android" {
346 return
347 }
348
349 C.lockOSThreadC()
350 }
351
352
353 func lockOSThreadCallback() {
354 runtime.LockOSThread()
355 runtime.UnlockOSThread()
356 go C.usleep(10000)
357 runtime.Gosched()
358 }
359
360
361
362 var issue4054b = []int{C.A, C.B, C.C, C.D, C.E, C.F, C.G, C.H, C.II, C.J}
363
364
365 func issue5548FromC(s string, i int) int {
366 if len(s) == 4 && s == "test" && i == 42 {
367 return 12345
368 }
369 println("got", len(s), i)
370 return 9876
371 }
372
373 func test5548(t *testing.T) {
374 if x := C.issue5548_in_c(); x != 12345 {
375 t.Errorf("issue5548_in_c = %d, want %d", x, 12345)
376 }
377 }
378
379
380
381
382 func GoIssue6833Func(aui uint, aui64 uint64) uint64 {
383 return aui64 + uint64(aui)
384 }
385
386 func test6833(t *testing.T) {
387 ui := 7
388 ull := uint64(0x4000300020001000)
389 v := uint64(C.issue6833Func(C.uint(ui), C.ulonglong(ull)))
390 exp := uint64(ui) + ull
391 if v != exp {
392 t.Errorf("issue6833Func() returns %x, expected %x", v, exp)
393 }
394 }
395
396
397
398 const CString = "C string"
399
400
401 func CheckIssue6907Go(s string) C.int {
402 if s == CString {
403 return 1
404 }
405 return 0
406 }
407
408 func test6907Go(t *testing.T) {
409 if got := C.CheckIssue6907C(CString); got != 1 {
410 t.Errorf("C.CheckIssue6907C() == %d, want %d", got, 1)
411 }
412 }
413
414
415
416 var bad7665 unsafe.Pointer = C.f7665
417 var good7665 uintptr = uintptr(C.f7665)
418
419 func test7665(t *testing.T) {
420 if bad7665 == nil || uintptr(bad7665) != good7665 {
421 t.Errorf("ptrs = %p, %#x, want same non-nil pointer", bad7665, good7665)
422 }
423 }
424
425
426
427 var issue7978sync uint32
428
429 func issue7978check(t *testing.T, wantFunc string, badFunc string, depth int) {
430 runtime.GC()
431 buf := make([]byte, 65536)
432 trace := string(buf[:runtime.Stack(buf, true)])
433 for _, goroutine := range strings.Split(trace, "\n\n") {
434 if strings.Contains(goroutine, "test.issue7978go") {
435 trace := strings.Split(goroutine, "\n")
436
437 for i := 0; i < depth; i++ {
438 if badFunc != "" && strings.Contains(trace[1+2*i], badFunc) {
439 t.Errorf("bad stack: found %s in the stack:\n%s", badFunc, goroutine)
440 return
441 }
442 if strings.Contains(trace[1+2*i], wantFunc) {
443 return
444 }
445 }
446 t.Errorf("bad stack: didn't find %s in the stack:\n%s", wantFunc, goroutine)
447 return
448 }
449 }
450 t.Errorf("bad stack: goroutine not found. Full stack dump:\n%s", trace)
451 }
452
453 func issue7978wait(store uint32, wait uint32) {
454 if store != 0 {
455 atomic.StoreUint32(&issue7978sync, store)
456 }
457 for atomic.LoadUint32(&issue7978sync) != wait {
458 runtime.Gosched()
459 }
460 }
461
462
463 func issue7978cb() {
464
465
466 growStack(64)
467 issue7978wait(3, 4)
468 }
469
470 func growStack(n int) int {
471 var buf [128]int
472 if n == 0 {
473 return 0
474 }
475 return buf[growStack(n-1)]
476 }
477
478 func issue7978go() {
479 C.issue7978c((*C.uint32_t)(&issue7978sync))
480 issue7978wait(7, 8)
481 }
482
483 func test7978(t *testing.T) {
484 if runtime.Compiler == "gccgo" {
485 t.Skip("gccgo can not do stack traces of C code")
486 }
487 debug.SetTraceback("2")
488 issue7978sync = 0
489 go issue7978go()
490
491 issue7978wait(0, 1)
492 issue7978check(t, "_Cfunc_issue7978c(", "", 1)
493
494 issue7978wait(2, 3)
495 issue7978check(t, "test.issue7978cb(", "test.issue7978go", 3)
496
497 issue7978wait(4, 5)
498 issue7978check(t, "_Cfunc_issue7978c(", "_cgoexpwrap", 1)
499
500 issue7978wait(6, 7)
501 issue7978check(t, "test.issue7978go(", "", 3)
502 atomic.StoreUint32(&issue7978sync, 8)
503 }
504
505
506
507 var issue8331Var C.issue8331
508
509
510
511
512 func Test8945() {
513 _ = C.func8945
514 }
515
516
517
518
519 func multi() (*C.char, C.int) {
520 return C.CString("multi"), 0
521 }
522
523 func test20910(t *testing.T) {
524 C.callMulti()
525 }
526
527
528
529 const issue28772Constant2 = C.issue28772Constant2
530
531
532
533
534 func useIssue31891A(c *C.Issue31891A) {}
535
536
537 func useIssue31891B(c *C.Issue31891B) {}
538
539 func test31891(t *testing.T) {
540 C.callIssue31891()
541 }
542
543
544
545 var issue37033 = 42
546
547
548 func GoFunc37033(handle C.uintptr_t) {
549 h := cgo.Handle(handle)
550 ch := h.Value().(chan int)
551 ch <- issue37033
552 }
553
554
555
556
557 var _ C.PIssue38408 = &C.Issue38408{i: 1}
558
559
560
561 type data49633 struct {
562 msg string
563 }
564
565
566 func GoFunc49633(context unsafe.Pointer) {
567 h := *(*cgo.Handle)(context)
568 v := h.Value().(*data49633)
569 v.msg = "hello"
570 }
571
572 func test49633(t *testing.T) {
573 v := &data49633{}
574 h := cgo.NewHandle(v)
575 defer h.Delete()
576 C.cfunc49633(unsafe.Pointer(&h))
577 if v.msg != "hello" {
578 t.Errorf("msg = %q, want 'hello'", v.msg)
579 }
580 }
581
View as plain text