Source file src/runtime/testdata/testprogcgo/issue63739.go
1 // Copyright 2020 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 5 package main 6 7 // This is for issue #63739. 8 // Ensure that parameters are kept alive until the end of the C call. If not, 9 // then a stack copy at just the right time while calling into C might think 10 // that any stack pointers are not alive and fail to update them, causing the C 11 // function to see the old, no longer correct, pointer values. 12 13 /* 14 int add_from_multiple_pointers(int *a, int *b, int *c) { 15 *a = *a + 1; 16 *b = *b + 1; 17 *c = *c + 1; 18 return *a + *b + *c; 19 } 20 #cgo noescape add_from_multiple_pointers 21 #cgo nocallback add_from_multiple_pointers 22 */ 23 import "C" 24 25 import ( 26 "fmt" 27 ) 28 29 const ( 30 maxStack = 1024 31 ) 32 33 func init() { 34 register("CgoEscapeWithMultiplePointers", CgoEscapeWithMultiplePointers) 35 } 36 37 func CgoEscapeWithMultiplePointers() { 38 stackGrow(maxStack) 39 fmt.Println("OK") 40 } 41 42 //go:noinline 43 func testCWithMultiplePointers() { 44 var a C.int = 1 45 var b C.int = 2 46 var c C.int = 3 47 v := C.add_from_multiple_pointers(&a, &b, &c) 48 if v != 9 || a != 2 || b != 3 || c != 4 { 49 fmt.Printf("%d + %d + %d != %d\n", a, b, c, v) 50 } 51 } 52 53 func stackGrow(n int) { 54 if n == 0 { 55 return 56 } 57 testCWithMultiplePointers() 58 stackGrow(n - 1) 59 } 60