英文:
out of memory panic while accessing a function from a shared library
问题
我正在尝试使用Go构建一个示例共享对象库。代码编译成功(使用命令go build -o libsample.so -buildmode=c-shared .
),成功构建了一个共享对象库。但是,在通过JNA(从Java)或ctypes(从Python)访问导出的方法时,我遇到了一个错误。
我在Go中编写的代码如下:
// package name: libsample.so
package main
import "C"
import "fmt"
//export Hello
func Hello(s string) {
fmt.Println("Hello " + s + "!")
}
func main() {
}
在Java中访问这个方法Hello
时:
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");
}
}
或者在Python中访问:
#!/usr/bin/python
import ctypes
lib = ctypes.CDLL("./libsample.so")
lib.Hello("World")
我得到了以下错误:
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)
出了什么问题?如果我使用int
或float
作为参数创建方法,就不会出现这个错误。
英文:
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
得分: 7
原因:
这是因为你的go函数Hello
期望一个golang
字符串,但是Python和Java传递了一个C风格
的字符串。
解决方案:
由于你使用了buildmode=c-shared
编译你的golang库,Python的ctypes
包和Java的JNI将其视为普通的C方法,并传递了一个C风格的字符串,实际上只是一个以NULL
结尾的字符数组。
但是在你的代码中,函数Hello
期望一个golang字符串,它的格式与典型的C风格字符串不同。因此会出现这个错误。
可以通过将s
声明为*C.char
来解决这个问题。
修正后的程序如下:
// 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() {
}
英文:
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() {
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论