Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/cgo: clarify safety of calling unsafe.Slice and unsafe.String with C pointers #68832

Closed
arvidfm opened this issue Aug 10, 2024 · 3 comments
Closed
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.

Comments

@arvidfm
Copy link

arvidfm commented Aug 10, 2024

Go version

1.22.6

Output of go env in your module/workspace:

N/A

What did you do?

N/A

What did you see happen?

The documentation for cmd/cgo#Passing pointers states that strings and slices always contain Go pointers:

Note that values of some Go types, other than the type's zero value, always include Go pointers. This is true of string, slice, interface, channel, map, and function types.

This seems to imply that the following is UB, as it constructs a slice from a C pointer rather than a Go pointer:

//export processData
func processData(ptr unsafe.Pointer, len C.size_t) {
	s := unsafe.Slice((*byte)(ptr), len)
	fmt.Println("got data:", string(s))
}

However, discussion on the Gophers Slack suggests that this may actually be perfectly fine, as Go should still know whether a pointer points to memory managed by Go. syscall.Mmap was mentioned as an example of a slice not backed by Go-managed memory.

What did you expect to see?

Accurate information in the Cgo documentation regarding the safety of strings and slices backed by C-managed memory.

In either case, an explicit description of the safety or non-safety of passing a C pointer would be appreciated in the documentation for unsafe.String and unsafe.Slice.

As an aside, it would also be good to document any other invariants that must be upheld by the data passed to unsafe.String, if applicable. In particular, whether the string must be valid UTF-8, and whether it may contain null bytes.

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Aug 10, 2024
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/604715 mentions this issue: cmd/cgo: clarify that strings and slices may contain C pointers

@cagedmantis cagedmantis added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Aug 12, 2024
@ianlancetaylor
Copy link
Member

I committed a patch to clarify the cgo docs.

I don't think that unsafe.String or unsafe.Slice are the right place to discuss C pointers.

Go defines strings as a sequence of bytes (for example, https://go.dev/ref/spec#String_types). As such, there are no restrictions on the bytes passed to unsafe.String. They need not be UTF-8, they may contain NUL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants