PtrGuard: a new package to break the Cgo pointer passing rules

152 views
Skip to first unread message

Sven Anderson

unread,
Jun 30, 2021, 12:18:47 PM6/30/21
to golan...@googlegroups.com
Dear nuts,

because we needed to use iovec APIs like the readv/writev system calls and wanted to avoid an additional memory copy, we needed to store Go pointers in C memory, or pass a Go pointer to memory that contains other Go pointers. In other words we needed to break the Cgo pointer passing rules. The solution I came up with I wrapped up in the package PtrGuard[1]. I know, since Go doesn't have a moving Garbage Collector yet, this all is not strictly necessary, but I wanted to have a PoC to be prepared, when it might come. Also it was an interesting exercise. :-)

From README:
PtrGuard is a small Go package that allows to pin a Go pointer (that is pointing to memory allocated by the Go runtime) within a Scope(). The scope provides a Pinner which can pin a Go pointer with the Pin() method, so that the pointer will not be touched by the garbage collector until the scope is left. Therefore the pinned Go pointer can either be directly stored in C memory with the Poke() method, or is allowed to be contained in Go memory that is passed to C functions, which both usually violates the pointer passing rules. In the second case you might need the NoCheck() method to call the C function in a context, where the cgocheck debug feature is disabled, because PtrGuard doesn't have any possibility so far to tell cgocheck, that certain pointers are pinned.

I would be very interested in getting feedback of any kind. Is it useful, is it broken, are there better ways to realize that? So, many thanks in advance to everyone that will have a look!

I also created a related Go proposal[2], because I think in the end such a package shouldn't be necessary.


Cheers,

Sven

Ian Lance Taylor

unread,
Jun 30, 2021, 12:55:51 PM6/30/21
to Sven Anderson, golang-nuts
That's pretty clever. I guess my only concern is that we've
documented //go:uintptrescapes with "This directive is necessary for
some low-level system call implementations and should be avoided
otherwise."

Ian
Reply all
Reply to author
Forward
0 new messages