c-for-go icon indicating copy to clipboard operation
c-for-go copied to clipboard

generated function with []string parameter produces panic with "fatal error: Go pointer stored into non-Go memory"

Open laser opened this issue 5 years ago • 0 comments

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?

laser avatar May 04 '20 23:05 laser