Closed
Description
Assume you have some package foo that uses a C function:
package foo
/*
typedef struct Buf {
} Buf;
void Foo(Buf* buf) {
}
*/
import "C"
func Foo() {
var buf C.Buf
C.Foo(&buf)
}
If you compile this package with Go 1.2 (what we use, until we can do some big audit of our cgo usage), we get this:
andrew@andrew-cb:~/escapeme/src/foo$ go version
go version go1.2 linux/amd64
andrew@andrew-cb:~/escapeme/src/foo$ go build -gcflags "-m -l -N"
# foo
./foo.go:14: moved to heap: buf
This is what we'd expect. Since the heap is (currently) a safe place to put Go-allocated memory referenced by C, we'd expect passing &buf to C.Foo to indicate buf should be heap-allocated.
On Go 1.4, we get this:
andrew@andrew-cb:~/escapeme/src/foo$ go version
go version go1.4.2 linux/amd64
andrew@andrew-cb:~/escapeme/src/foo$ go build -gcflags "-m -l -N"
# foo
/tmp/go-build929685257/foo/_obj/_cgo_gotypes.go:12: leaking param: ptr to result ~r1
:10[/tmp/go-build929685257/foo/_obj/_cgo_gotypes.go:27]: _Cfunc_Foo p0 does not escape
:11[/tmp/go-build929685257/foo/_obj/_cgo_gotypes.go:28]: _Cfunc_Foo &p0 does not escape
./foo.go:15: Foo &buf does not escape
andrew@andrew-cb:~/escapeme/src/foo$
Foo &buf does not escape? It totally should! Since it didn't get escaped, we're now passing stack-allocated memory into C. Holy cow that's a bad idea with 1.4, cause stack allocated memory gets moved around.
And here's tip:
andrew@andrew-cb:~/escapeme/src/foo$ go version
go version devel +f8fd550 Tue Mar 31 13:56:18 2015 +0000 linux/amd64
andrew@andrew-cb:~/escapeme/src/foo$ go build -gcflags "-m -l -N"
# foo
/tmp/go-build207622607/foo/_obj/_cgo_gotypes.go:14: leaking param: ptr to result ~r1
:19[/tmp/go-build207622607/foo/_obj/_cgo_gotypes.go:38]: _Cfunc_Foo p0 does not escape
:20[/tmp/go-build207622607/foo/_obj/_cgo_gotypes.go:39]: _Cfunc_Foo &p0 does not escape
./foo.go:15: Foo &buf does not escape
andrew@andrew-cb:~/escapeme/src/foo$