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