Thanks for replying.

So if I'm tracking you correctly, that it is not okay to:

    1. store a Go pointer in a C struct
    2. and then pass a pointer to that struct to C code

Then doesn't that mean that the bzip2 example from GOPL is also wrong? It
does both:

    1. stores a Go pointer (in Go
    in a C struct (in C
    2. and then pass a pointer to that struct to C code (in C

On Wednesday, November 18, 2015 at 7:05:03 AM UTC-8, Ian Lance Taylor wrote:

On Wed, Nov 18, 2015 at 12:13 AM, <thebroke...@gmail.com <javascript:>>
I was looking at the source for
github.com/youtube/vitess/go/cgzip/zstream.go, and it curiously says:
// z_stream is a buffer that's big enough to fit a C.z_stream.
// This lets us allocate a C.z_stream within Go, while keeping the
// opaque to the Go GC. Otherwise, the GC would look inside and
// the pointers are invalid, since they point to objects allocated by C

Before the commit that changed this, the previous implementation simply
declared type zstream C.z_stream, instead of the complicated array of bytes
it is now. When I run the package prior to the change, my program crashes
randomly with:
runtime:objectstart Span weird: p=0xc8206c2000 k=0x6410361
s.start=0xc8206c2000 s.limit=0xc820220000 s.state=2
fatal error: objectstart: bad pointer in unexpected span
which is oddly similar to issue 13289.

My questions is (assuming the above comment is correct): if the Go compiler
knows that zstream is just a C struct, why does it care about the pointers
inside the C struct when they almost certainly managed by a C malloc
instead? Also, doesn't the bzip2 example from The Go Programming Language
pretty much do things the way that cgzip moved away from?
Whether a struct is a C struct or a Go struct is irrelevant to the GC.
It's fine to have a C struct, and it's fine to have a C struct that
has pointers, and it's fine to store Go pointers in a C struct. What
is not fine is storing Go pointers in a C struct and then passing a
pointer to that struct into C code. The code you mention appears to
do exactly that. The setInBuf and setOutBuf methods appear to take Go
pointers and store them in the C struct. Other methods later pass the
struct to C. The commit you mention hides this fact from the GC by
changing the type of the struct so that the GC doesn't see the
pointers, but the code remains broken. Previously the GC was
detecting a dangling pointer. Now the pointer is dangling but nobody
is noticing. This code should be fixed.

You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

Discussion Posts


Follow ups

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 3 of 6 | next ›
Discussion Overview
groupgolang-nuts @
postedNov 18, '15 at 8:13a
activeNov 19, '15 at 3:03a



site design / logo © 2021 Grokbase