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