c-for-go
c-for-go copied to clipboard
generated function with []string parameter produces panic with "fatal error: Go pointer stored into non-Go memory"
Given the following header:
# demo.h
uint8_t count_colors(const char *const *colors_ptr, size_t colors_len);
When I generate bindings using the following configuration:
---
GENERATOR:
PackageName: generated
PackageDescription:
PackageLicense:
Options:
SafeStrings: true
Includes:
- ../demo.h
FlagGroups:
- {name: LDFLAGS, flags: ["-L${SRCDIR}/.. -ldemo"]}
- {name: pkg-config, flags: ["${SRCDIR}/../demo.pc"]}
PARSER:
Defines:
__has_include_next(x): 1
IncludePaths:
- /usr/include
SourcesPaths:
- ./demo.h
TRANSLATOR:
ConstRules:
defines: expand
enum: cgo
Rules:
global:
- {action: accept, from: "^count"}
- {transform: export}
private:
- {transform: unexport}
post-global:
- {transform: export}
- {load: snakecase}
...I get the following generated Go function:
func CountColors(colorsPtr []string, colorsLen uint) byte {
// generated implementation
}
When I call that function with GODEBUG=cgocheck=2, I see a panic:
16:17 $ GODEBUG=cgocheck=2 go test . -count=1 -run=^TestHambone$ -v
=== RUN TestHambone
write of Go pointer 0xc000027b48 to non-Go memory 0x8900000
fatal error: Go pointer stored into non-Go memory
runtime stack:
runtime.throw(0x4f6c467, 0x24)
/usr/local/go/src/runtime/panic.go:774 +0x72
runtime.cgoCheckWriteBarrier.func1()
/usr/local/go/src/runtime/cgocheck.go:55 +0xa9
runtime.systemstack(0x7ffeefbff028)
/usr/local/go/src/runtime/asm_amd64.s:370 +0x66
runtime.mstart()
/usr/local/go/src/runtime/proc.go:1146
goroutine 6 [running]:
runtime.systemstack_switch()
/usr/local/go/src/runtime/asm_amd64.s:330 fp=0xc000058cc8 sp=0xc000058cc0 pc=0x405e820
runtime.cgoCheckWriteBarrier(0x8900000, 0xc000027b48)
/usr/local/go/src/runtime/cgocheck.go:53 +0xc9 fp=0xc000058d00 sp=0xc000058cc8 pc=0x4006bd9
runtime.wbBufFlush(0x8900000, 0xc000027b48)
/usr/local/go/src/runtime/mwbbuf.go:196 +0x83 fp=0xc000058d30 sp=0xc000058d00 pc=0x402d2e3
runtime.gcWriteBarrier(0x0, 0x4f5f8c9, 0x3, 0x4f5f5cf, 0x1, 0xc000027b48, 0x4, 0x0, 0x1000000000020, 0xc000058db8, ...)
/usr/local/go/src/runtime/asm_amd64.s:1444 +0xae fp=0xc000058db8 sp=0xc000058d30 pc=0x406098e
github.com/filecoin-project/filecoin-ffi/generated.unpackArgSString(0xc000058f40, 0x2, 0x2, 0x0, 0xc000010900)
/Users/erinswenson-healey/dev/filecoin-ffi/generated/cgo_helpers.go:3366 +0x208 fp=0xc000058ea0 sp=0xc000058db8 pc=0x437d4e8
github.com/filecoin-project/filecoin-ffi/generated.CountColors(0xc000058f40, 0x2, 0x2, 0x2, 0xc000058f60)
/Users/erinswenson-healey/dev/filecoin-ffi/generated/generated.go:838 +0x43 fp=0xc000058ef8 sp=0xc000058ea0 pc=0x4383043
github.com/filecoin-project/filecoin-ffi.TestHambone(0xc000132100)
/Users/erinswenson-healey/dev/filecoin-ffi/proofs_test.go:45 +0x62 fp=0xc000058f70 sp=0xc000058ef8 pc=0x43b5af2
testing.tRunner(0xc000132100, 0x4f7c1b0)
/usr/local/go/src/testing/testing.go:909 +0xc9 fp=0xc000058fd0 sp=0xc000058f70 pc=0x40f8959
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1357 +0x1 fp=0xc000058fd8 sp=0xc000058fd0 pc=0x40608d1
created by testing.(*T).Run
/usr/local/go/src/testing/testing.go:960 +0x350
goroutine 1 [chan receive]:
testing.(*T).Run(0xc000132100, 0x4f618cf, 0xb, 0x4f7c1b0, 0x1)
/usr/local/go/src/testing/testing.go:961 +0x377
testing.runTests.func1(0xc000132000)
/usr/local/go/src/testing/testing.go:1202 +0x78
testing.tRunner(0xc000132000, 0xc00011fdc0)
/usr/local/go/src/testing/testing.go:909 +0xc9
testing.runTests(0xc0000108a0, 0x5442000, 0xa, 0xa, 0x0)
/usr/local/go/src/testing/testing.go:1200 +0x2a7
testing.(*M).Run(0xc000126180, 0x0)
/usr/local/go/src/testing/testing.go:1117 +0x176
main.main()
_testmain.go:70 +0x135
FAIL github.com/filecoin-project/filecoin-ffi 0.016s
FAIL
The generates code is using unpackPCharString under the hood. Is there some way to defeat this behavior, instead copying the string from the Go to C heap?