Skip to content

cmd/cgo: should make pointers passed to C functions escape #10303

Closed
@jtolio

Description

@jtolio

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$ 

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions