out of memory panic while accessing a function from a shared library
Question: I'm trying to build a sample shared object library using Go. The code compiles
(using the command `go build -o libsample.so -buildmode=c-shared .`), a shared
object library is built successfully - but while accessing the exported method
via JNA(from Java) or ctypes (from python), I am getting a panic. The code I
wrote in Go is:

    
    
    // package name: libsample.so
    package main
    
    import "C"
    import "fmt"
    
    //export Hello
    func Hello(s string) {
        fmt.Println("Hello " + s + "!")
    }
    
    func main() {
    }
    

While accessing this method `Hello` from Java:

    
    
    import com.sun.jna.*;
    
    public class sample {
    
        public interface GoSO extends Library {
            GoSO INSTANCE = (GoSO) Native.loadLibrary("sample" ,GoSO.class);
            void Hello(String s);
        }
        public static void main(String[] args) {
            GoSO.INSTANCE.Hello("World");
        }
    }
    

or from Python:

    
    
    #!/usr/bin/python
    import ctypes
    lib = ctypes.CDLL("./libsample.so")
    lib.Hello("World")
    

I get the following error:

    
    
    runtime: out of memory: cannot allocate 140042998120448-byte block (1048576 in use)
    fatal error: out of memory
    
    runtime stack:
    runtime.throw(0x7f5e434bfe50, 0xd)
        /usr/local/go/src/runtime/panic.go:530 +0x92
    runtime.largeAlloc(0x7f5e4d27dc8d, 0xc800000003, 0xc82003cf08)
        /usr/local/go/src/runtime/malloc.go:768 +0xdf
    runtime.mallocgc.func3()
        /usr/local/go/src/runtime/malloc.go:664 +0x35
    runtime.systemstack(0x7f5e4e4d3ab8)
        /usr/local/go/src/runtime/asm_amd64.s:291 +0x72
    runtime.mstart()
        /usr/local/go/src/runtime/proc.go:1048
    
    goroutine 17 [running, locked to thread]:
    runtime.systemstack_switch()
        /usr/local/go/src/runtime/asm_amd64.s:245 fp=0xc82003cb50 sp=0xc82003cb48
    runtime.mallocgc(0x7f5e4d27dc8d, 0x0, 0x3, 0x0)
        /usr/local/go/src/runtime/malloc.go:665 +0x9fe fp=0xc82003cc28 sp=0xc82003cb50
    runtime.rawstring(0x7f5e4d27dc8d, 0x0, 0x0, 0x0, 0x0, 0x0)
        /usr/local/go/src/runtime/string.go:284 +0x72 fp=0xc82003cc70 sp=0xc82003cc28
    runtime.rawstringtmp(0x0, 0x7f5e4d27dc8d, 0x0, 0x0, 0x0, 0x0, 0x0)
        /usr/local/go/src/runtime/string.go:111 +0xb9 fp=0xc82003cca8 sp=0xc82003cc70
    runtime.concatstrings(0x0, 0xc82003ce38, 0x3, 0x3, 0x0, 0x0)
        /usr/local/go/src/runtime/string.go:49 +0x1bf fp=0xc82003cde0 sp=0xc82003cca8
    runtime.concatstring3(0x0, 0x7f5e434ba9d0, 0x6, 0x7f5e48155490, 0x7f5e4d27dc86, 0x7f5e434ba560, 0x1, 0x0, 0x0)
        /usr/local/go/src/runtime/string.go:63 +0x6c fp=0xc82003ce30 sp=0xc82003cde0
    main.Hello(0x7f5e48155490, 0x7f5e4d27dc86)
        /home/vagrant/go/src/github.com/venkatramachandran/lib-sample/sample.go:9 +0x72 fp=0xc82003cec8 sp=0xc82003ce30
    main._cgoexpwrap_9f7405a93e67_Hello(0x7f5e48155490, 0x7f5e4d27dc86)
        github.com/venkatramachandran/lib-sample/_obj/_cgo_gotypes.go:48 +0x2d fp=0xc82003cee0 sp=0xc82003cec8
    runtime.call32(0x0, 0x7f5e4e4d3ae8, 0x7f5e4e4d3b70, 0x10)
        /usr/local/go/src/runtime/asm_amd64.s:472 +0x40 fp=0xc82003cf08 sp=0xc82003cee0
    runtime.cgocallbackg1()
        /usr/local/go/src/runtime/cgocall.go:267 +0x110 fp=0xc82003cf40 sp=0xc82003cf08
    runtime.cgocallbackg()
        /usr/local/go/src/runtime/cgocall.go:180 +0xd9 fp=0xc82003cfa0 sp=0xc82003cf40
    runtime.cgocallback_gofunc(0x0, 0x0, 0x0)
        /usr/local/go/src/runtime/asm_amd64.s:716 +0x5d fp=0xc82003cfb0 sp=0xc82003cfa0
    runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1998 +0x1 fp=0xc82003cfb8 sp=0xc82003cfb0
    
    goroutine 18 [syscall, locked to thread]:
    runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1998 +0x1
    Aborted (core dumped)
    

What is going wrong? If I create method with an `int` or a `float` as a
parameter, this error does not occur.


Answer: **Reason:** The reason behind this is that your go function `Hello` expects a
`golang` String, but python and Java passed `C style` string.

**Solution:** Since you have compiled your golang library using
`buildmode=c-shared`. Python `ctypes` package and java JNI views it as a plain
c method. And passes a c style string which is really just an array of
characters terminated by `NULL`.

But in your code, function `Hello` expects a golang string, which has
different format than typical c style string. Hence this error.

It can be solved by declaring `s` as `*C.char`.

Corrected program is as follows:

    
    
    // package name: libsample.so
    package main
    
    import "C"
    import "fmt"
    
    //export Hello
    func Hello(s *C.char) {
        fmt.Println("Hello " + C.GoString(s) + "!")
    }
    
    func main() {
    }
    

