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

Cant store json in ybc using golang #14

Open
vektah opened this issue Apr 14, 2016 · 4 comments
Open

Cant store json in ybc using golang #14

vektah opened this issue Apr 14, 2016 · 4 comments
Labels

Comments

@vektah
Copy link

vektah commented Apr 14, 2016

Not sure what is going on here...

package main

import (
    "encoding/json"
    "github.com/valyala/ybc/bindings/go/ybc"
    "time"
)

func main() {
    cfg := &ybc.Config{
        DataFileSize:  ybc.SizeT(10240),
        MaxItemsCount: ybc.SizeT(100),
        IndexFile:     "foo.idx",
        DataFile:      "foo.dat",
    }
    cache, err := cfg.OpenCache(true)
    if err != nil {
        panic(err)
    }

    b, err := json.Marshal(123)
    if err != nil {
        panic(err)
    }

    if err = cache.Set([]byte("key"), b, time.Hour); err != nil {
        panic(err)
    }
}

gives

[adam@scopuli ~]$ go run test.go 
panic: runtime error: cgo argument has Go pointer to Go pointer

goroutine 1 [running]:
panic(0x5123a0, 0xc82000a430)
        /usr/lib/go/src/runtime/panic.go:464 +0x3e6
github.com/valyala/ybc/bindings/go/ybc.(*Cache).Set(0xc82000e2e0, 0xc82000a410, 0x3, 0x8, 0xc820082024, 0x3, 0x40, 0x34630b8a000, 0x0, 0x0)
        /home/adam/go/src/github.com/valyala/ybc/bindings/go/ybc/ybc.go:457 +0x385
main.main()
        /home/adam/test.go:26 +0x226
exit status 2

However, this works fine:

cache.Set([]byte("key"), []byte(string(b)), time.Hour);

Running:

go version go1.6 linux/amd64

and ybc 82bc72dc617945514a43056c92c023f65e045ae6
@valyala valyala added the bug label Apr 15, 2016
@valyala
Copy link
Owner

valyala commented Apr 15, 2016

This looks like a bug in Go runtime. Will try narrowing down it and posting to Go issue tracker.

@valyala
Copy link
Owner

valyala commented Apr 15, 2016

As a temporary workaround you can use GODEBUG="cgocheck=0" environment variable for disabling cgo check. See Environment Variables chapter in runtime package for details.

@valyala
Copy link
Owner

valyala commented Apr 15, 2016

Minimized it to:

package main

// static void foo(void *p) {}
import "C"

import (
    "encoding/json"
    "unsafe"
)

func main() {
    b, err := json.Marshal(123)
    if err != nil {
        panic(err)
    }
    p := unsafe.Pointer(&b[0])
    C.foo(p)
}

@valyala
Copy link
Owner

valyala commented Apr 16, 2016

There is another workaround mentioned in the linked Go issue:

What is messing up is that encoding/json uses a 64 byte buffer in a larger struct, and if the encoding requires 64 bytes or fewer than the resulting pointer is into that struct. So one workaround is

if len(b) <= 64 {
    b = append([]byte(nil), b...)
}
if err = cache.Set([]byte("key"), b, time.Hour); err != nil {
        panic(err)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants