testx.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. // Copyright 2011 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. // Test cases for cgo.
  5. // Both the import "C" prologue and the main file are sorted by issue number.
  6. // This file contains //export directives on Go functions
  7. // and so it must NOT contain C definitions (only declarations).
  8. // See test.go for C definitions.
  9. package cgotest
  10. import (
  11. "runtime"
  12. "runtime/cgo"
  13. "runtime/debug"
  14. "strings"
  15. "sync"
  16. "sync/atomic"
  17. "testing"
  18. "time"
  19. "unsafe"
  20. )
  21. /*
  22. // threads
  23. extern void doAdd(int, int);
  24. // issue 1328
  25. void IntoC(void);
  26. // issue 1560
  27. // mysleep returns the absolute start time in ms.
  28. long long mysleep(int seconds);
  29. // twoSleep returns the absolute start time of the first sleep
  30. // in ms.
  31. long long twoSleep(int);
  32. // issue 3775
  33. void lockOSThreadC(void);
  34. int usleep(unsigned usec);
  35. // issue 4054 part 2 - part 1 in test.go
  36. typedef enum {
  37. A = 0,
  38. B,
  39. C,
  40. D,
  41. E,
  42. F,
  43. G,
  44. H,
  45. II,
  46. J,
  47. } issue4054b;
  48. // issue 5548
  49. extern int issue5548_in_c(void);
  50. // issue 6833
  51. extern unsigned long long issue6833Func(unsigned int, unsigned long long);
  52. // issue 6907
  53. extern int CheckIssue6907C(_GoString_);
  54. // issue 7665
  55. extern void f7665(void);
  56. // issue 7978
  57. // Stack tracing didn't work during cgo code after calling a Go
  58. // callback. Make sure GC works and the stack trace is correct.
  59. #include <stdint.h>
  60. // use ugly atomic variable sync since that doesn't require calling back into
  61. // Go code or OS dependencies
  62. void issue7978c(uint32_t *sync);
  63. // issue 8331 part 2 - part 1 in test.go
  64. // A typedef of an unnamed struct is the same struct when
  65. // #include'd twice. No runtime test; just make sure it compiles.
  66. #include "issue8331.h"
  67. // issue 8945
  68. typedef void (*PFunc8945)();
  69. extern PFunc8945 func8945; // definition is in test.go
  70. // issue 20910
  71. void callMulti(void);
  72. // issue 28772 part 2 - part 1 in issuex.go
  73. #define issue28772Constant2 2
  74. // issue 31891
  75. typedef struct {
  76. long obj;
  77. } Issue31891A;
  78. typedef struct {
  79. long obj;
  80. } Issue31891B;
  81. void callIssue31891(void);
  82. typedef struct {
  83. int i;
  84. } Issue38408, *PIssue38408;
  85. extern void cfunc49633(void*); // definition is in test.go
  86. */
  87. import "C"
  88. // exports
  89. //export ReturnIntLong
  90. func ReturnIntLong() (int, C.long) {
  91. return 1, 2
  92. }
  93. //export gc
  94. func gc() {
  95. runtime.GC()
  96. }
  97. // threads
  98. var sum struct {
  99. sync.Mutex
  100. i int
  101. }
  102. //export Add
  103. func Add(x int) {
  104. defer func() {
  105. recover()
  106. }()
  107. sum.Lock()
  108. sum.i += x
  109. sum.Unlock()
  110. var p *int
  111. *p = 2
  112. }
  113. func testCthread(t *testing.T) {
  114. if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && runtime.GOARCH == "arm64" {
  115. t.Skip("the iOS exec wrapper is unable to properly handle the panic from Add")
  116. }
  117. sum.i = 0
  118. C.doAdd(10, 6)
  119. want := 10 * (10 - 1) / 2 * 6
  120. if sum.i != want {
  121. t.Fatalf("sum=%d, want %d", sum.i, want)
  122. }
  123. }
  124. // issue 1328
  125. //export BackIntoGo
  126. func BackIntoGo() {
  127. x := 1
  128. for i := 0; i < 10000; i++ {
  129. xvariadic(x)
  130. if x != 1 {
  131. panic("x is not 1?")
  132. }
  133. }
  134. }
  135. func xvariadic(x ...interface{}) {
  136. }
  137. func test1328(t *testing.T) {
  138. C.IntoC()
  139. }
  140. // issue 1560
  141. var sleepDone = make(chan int64)
  142. // parallelSleep returns the absolute difference between the start time
  143. // of the two sleeps.
  144. func parallelSleep(n int) int64 {
  145. t := int64(C.twoSleep(C.int(n))) - <-sleepDone
  146. if t < 0 {
  147. return -t
  148. }
  149. return t
  150. }
  151. //export BackgroundSleep
  152. func BackgroundSleep(n int32) {
  153. go func() {
  154. sleepDone <- int64(C.mysleep(C.int(n)))
  155. }()
  156. }
  157. func testParallelSleep(t *testing.T) {
  158. sleepSec := 1
  159. dt := time.Duration(parallelSleep(sleepSec)) * time.Millisecond
  160. t.Logf("difference in start time for two sleep(%d) is %v", sleepSec, dt)
  161. // bug used to run sleeps in serial, producing a 2*sleepSec-second delay.
  162. // we detect if the start times of those sleeps are > 0.5*sleepSec-second.
  163. if dt >= time.Duration(sleepSec)*time.Second/2 {
  164. t.Fatalf("parallel %d-second sleeps slept for %f seconds", sleepSec, dt.Seconds())
  165. }
  166. }
  167. // issue 2462
  168. //export exportbyte
  169. func exportbyte() byte {
  170. return 0
  171. }
  172. //export exportbool
  173. func exportbool() bool {
  174. return false
  175. }
  176. //export exportrune
  177. func exportrune() rune {
  178. return 0
  179. }
  180. //export exporterror
  181. func exporterror() error {
  182. return nil
  183. }
  184. //export exportint
  185. func exportint() int {
  186. return 0
  187. }
  188. //export exportuint
  189. func exportuint() uint {
  190. return 0
  191. }
  192. //export exportuintptr
  193. func exportuintptr() uintptr {
  194. return (uintptr)(0)
  195. }
  196. //export exportint8
  197. func exportint8() int8 {
  198. return 0
  199. }
  200. //export exportuint8
  201. func exportuint8() uint8 {
  202. return 0
  203. }
  204. //export exportint16
  205. func exportint16() int16 {
  206. return 0
  207. }
  208. //export exportuint16
  209. func exportuint16() uint16 {
  210. return 0
  211. }
  212. //export exportint32
  213. func exportint32() int32 {
  214. return 0
  215. }
  216. //export exportuint32
  217. func exportuint32() uint32 {
  218. return 0
  219. }
  220. //export exportint64
  221. func exportint64() int64 {
  222. return 0
  223. }
  224. //export exportuint64
  225. func exportuint64() uint64 {
  226. return 0
  227. }
  228. //export exportfloat32
  229. func exportfloat32() float32 {
  230. return 0
  231. }
  232. //export exportfloat64
  233. func exportfloat64() float64 {
  234. return 0
  235. }
  236. //export exportcomplex64
  237. func exportcomplex64() complex64 {
  238. return 0
  239. }
  240. //export exportcomplex128
  241. func exportcomplex128() complex128 {
  242. return 0
  243. }
  244. // issue 3741
  245. //export exportSliceIn
  246. func exportSliceIn(s []byte) bool {
  247. return len(s) == cap(s)
  248. }
  249. //export exportSliceOut
  250. func exportSliceOut() []byte {
  251. return []byte{1}
  252. }
  253. //export exportSliceInOut
  254. func exportSliceInOut(s []byte) []byte {
  255. return s
  256. }
  257. // issue 3775
  258. func init() {
  259. if runtime.GOOS == "android" {
  260. return
  261. }
  262. // Same as test3775 but run during init so that
  263. // there are two levels of internal runtime lock
  264. // (1 for init, 1 for cgo).
  265. // This would have been broken by CL 11663043.
  266. C.lockOSThreadC()
  267. }
  268. func test3775(t *testing.T) {
  269. if runtime.GOOS == "android" {
  270. return
  271. }
  272. // Used to panic because of the UnlockOSThread below.
  273. C.lockOSThreadC()
  274. }
  275. //export lockOSThreadCallback
  276. func lockOSThreadCallback() {
  277. runtime.LockOSThread()
  278. runtime.UnlockOSThread()
  279. go C.usleep(10000)
  280. runtime.Gosched()
  281. }
  282. // issue 4054 part 2 - part 1 in test.go
  283. var issue4054b = []int{C.A, C.B, C.C, C.D, C.E, C.F, C.G, C.H, C.II, C.J}
  284. //export issue5548FromC
  285. func issue5548FromC(s string, i int) int {
  286. if len(s) == 4 && s == "test" && i == 42 {
  287. return 12345
  288. }
  289. println("got", len(s), i)
  290. return 9876
  291. }
  292. func test5548(t *testing.T) {
  293. if x := C.issue5548_in_c(); x != 12345 {
  294. t.Errorf("issue5548_in_c = %d, want %d", x, 12345)
  295. }
  296. }
  297. // issue 6833
  298. //export GoIssue6833Func
  299. func GoIssue6833Func(aui uint, aui64 uint64) uint64 {
  300. return aui64 + uint64(aui)
  301. }
  302. func test6833(t *testing.T) {
  303. ui := 7
  304. ull := uint64(0x4000300020001000)
  305. v := uint64(C.issue6833Func(C.uint(ui), C.ulonglong(ull)))
  306. exp := uint64(ui) + ull
  307. if v != exp {
  308. t.Errorf("issue6833Func() returns %x, expected %x", v, exp)
  309. }
  310. }
  311. // issue 6907
  312. const CString = "C string"
  313. //export CheckIssue6907Go
  314. func CheckIssue6907Go(s string) C.int {
  315. if s == CString {
  316. return 1
  317. }
  318. return 0
  319. }
  320. func test6907Go(t *testing.T) {
  321. if got := C.CheckIssue6907C(CString); got != 1 {
  322. t.Errorf("C.CheckIssue6907C() == %d, want %d", got, 1)
  323. }
  324. }
  325. // issue 7665
  326. var bad7665 unsafe.Pointer = C.f7665
  327. var good7665 uintptr = uintptr(C.f7665)
  328. func test7665(t *testing.T) {
  329. if bad7665 == nil || uintptr(bad7665) != good7665 {
  330. t.Errorf("ptrs = %p, %#x, want same non-nil pointer", bad7665, good7665)
  331. }
  332. }
  333. // issue 7978
  334. var issue7978sync uint32
  335. func issue7978check(t *testing.T, wantFunc string, badFunc string, depth int) {
  336. runtime.GC()
  337. buf := make([]byte, 65536)
  338. trace := string(buf[:runtime.Stack(buf, true)])
  339. for _, goroutine := range strings.Split(trace, "\n\n") {
  340. if strings.Contains(goroutine, "test.issue7978go") {
  341. trace := strings.Split(goroutine, "\n")
  342. // look for the expected function in the stack
  343. for i := 0; i < depth; i++ {
  344. if badFunc != "" && strings.Contains(trace[1+2*i], badFunc) {
  345. t.Errorf("bad stack: found %s in the stack:\n%s", badFunc, goroutine)
  346. return
  347. }
  348. if strings.Contains(trace[1+2*i], wantFunc) {
  349. return
  350. }
  351. }
  352. t.Errorf("bad stack: didn't find %s in the stack:\n%s", wantFunc, goroutine)
  353. return
  354. }
  355. }
  356. t.Errorf("bad stack: goroutine not found. Full stack dump:\n%s", trace)
  357. }
  358. func issue7978wait(store uint32, wait uint32) {
  359. if store != 0 {
  360. atomic.StoreUint32(&issue7978sync, store)
  361. }
  362. for atomic.LoadUint32(&issue7978sync) != wait {
  363. runtime.Gosched()
  364. }
  365. }
  366. //export issue7978cb
  367. func issue7978cb() {
  368. // Force a stack growth from the callback to put extra
  369. // pressure on the runtime. See issue #17785.
  370. growStack(64)
  371. issue7978wait(3, 4)
  372. }
  373. func growStack(n int) int {
  374. var buf [128]int
  375. if n == 0 {
  376. return 0
  377. }
  378. return buf[growStack(n-1)]
  379. }
  380. func issue7978go() {
  381. C.issue7978c((*C.uint32_t)(&issue7978sync))
  382. issue7978wait(7, 8)
  383. }
  384. func test7978(t *testing.T) {
  385. if runtime.Compiler == "gccgo" {
  386. t.Skip("gccgo can not do stack traces of C code")
  387. }
  388. debug.SetTraceback("2")
  389. issue7978sync = 0
  390. go issue7978go()
  391. // test in c code, before callback
  392. issue7978wait(0, 1)
  393. issue7978check(t, "_Cfunc_issue7978c(", "", 1)
  394. // test in go code, during callback
  395. issue7978wait(2, 3)
  396. issue7978check(t, "test.issue7978cb(", "test.issue7978go", 3)
  397. // test in c code, after callback
  398. issue7978wait(4, 5)
  399. issue7978check(t, "_Cfunc_issue7978c(", "_cgoexpwrap", 1)
  400. // test in go code, after return from cgo
  401. issue7978wait(6, 7)
  402. issue7978check(t, "test.issue7978go(", "", 3)
  403. atomic.StoreUint32(&issue7978sync, 8)
  404. }
  405. // issue 8331 part 2
  406. var issue8331Var C.issue8331
  407. // issue 8945
  408. //export Test8945
  409. func Test8945() {
  410. _ = C.func8945
  411. }
  412. // issue 20910
  413. //export multi
  414. func multi() (*C.char, C.int) {
  415. return C.CString("multi"), 0
  416. }
  417. func test20910(t *testing.T) {
  418. C.callMulti()
  419. }
  420. // issue 28772 part 2
  421. const issue28772Constant2 = C.issue28772Constant2
  422. // issue 31891
  423. //export useIssue31891A
  424. func useIssue31891A(c *C.Issue31891A) {}
  425. //export useIssue31891B
  426. func useIssue31891B(c *C.Issue31891B) {}
  427. func test31891(t *testing.T) {
  428. C.callIssue31891()
  429. }
  430. // issue 37033, check if cgo.Handle works properly
  431. var issue37033 = 42
  432. //export GoFunc37033
  433. func GoFunc37033(handle C.uintptr_t) {
  434. h := cgo.Handle(handle)
  435. ch := h.Value().(chan int)
  436. ch <- issue37033
  437. }
  438. // issue 38408
  439. // A typedef pointer can be used as the element type.
  440. // No runtime test; just make sure it compiles.
  441. var _ C.PIssue38408 = &C.Issue38408{i: 1}
  442. // issue 49633, example use of cgo.Handle with void*
  443. type data49633 struct {
  444. msg string
  445. }
  446. //export GoFunc49633
  447. func GoFunc49633(context unsafe.Pointer) {
  448. h := *(*cgo.Handle)(context)
  449. v := h.Value().(*data49633)
  450. v.msg = "hello"
  451. }
  452. func test49633(t *testing.T) {
  453. v := &data49633{}
  454. h := cgo.NewHandle(v)
  455. defer h.Delete()
  456. C.cfunc49633(unsafe.Pointer(&h))
  457. if v.msg != "hello" {
  458. t.Errorf("msg = %q, want 'hello'", v.msg)
  459. }
  460. }