doudao9896 2016-04-07 17:13
浏览 87
已采纳

从共享库访问函数时出现内存不足紧急情况

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.

  • 写回答

1条回答 默认 最新

  • dtest84004 2016-04-07 18:14
    关注

    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() {
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 乘性高斯噪声在深度学习网络中的应用
  • ¥15 运筹学排序问题中的在线排序
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥30 求一段fortran代码用IVF编译运行的结果
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
  • ¥30 python代码,帮调试,帮帮忙吧