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