golang-ui / nuklear

This project provides Go bindings for nuklear.h — a small ANSI C GUI library.
https://github.com/vurtun/nuklear
MIT License
1.57k stars 98 forks source link

Crash with "fatal error: cgoUse should not be called" when using NkEditStringZeroTerminated #46

Closed wolfgang42 closed 5 years ago

wolfgang42 commented 6 years ago

Full test case here: https://gist.github.com/wolfgang42/07e8a2677c7f6e36393bdca862bebac2

From reading runtime/cgo.go it looks like somehow the nuklear bindings have gotten into some kind of can't happen state, but I don't know enough about how any of this works to be able to figure out how this could happen.

alexniver commented 5 years ago

i got the same problem

alexniver commented 5 years ago

from golang source code : https://github.com/golang/go/blob/master/src/runtime/cgo.go

// cgoUse is called by cgo-generated code (using go:linkname to get at // an unexported name). The calls serve two purposes: // 1) they are opaque to escape analysis, so the argument is considered to // escape to the heap. // 2) they keep the argument alive until the call site; the call is emitted after // the end of the (presumed) use of the argument by C. // cgoUse should not actually be called (see cgoAlwaysFalse). func cgoUse(interface{}) { throw("cgoUse should not be called") }

alexniver commented 5 years ago

I find the problem.

var textMaxLen = int32(64)
var textBuf = []byte{}
var textBufLen = int32(0)

if use var textBuf = []byte{}, this will cause textBuf change to a new ref in memory. to sovle this, use code below.

var textMaxLen = int32(64)
var textBuf = make([]byte, textMaxLen)
var textBufLen = int32(0)
xlab commented 5 years ago

@alexniver thank you for this solution! I never encountered it, because I always use the make() pattern. Also, it's a rule of thumb to only use pre-allocated memory, because C cannot allocate memory inside go structures. You must either allocate on Go side (using make) or on C side (malloc).

Thank you for looking into this.