Open wangzz719 opened 4 years ago
Thank you for this report @wangzhione and welcome to the Go project!
I can reproduce this even for Go1.13.12, Go1.12.17, but for Go1.11.13 there are CGO errors.
Kindly paging @ianlancetaylor @cherrymui
I tried to debug this problem, it crashed at method runtime.heapBitsSetType
.
After digging into the assembly,
(lldb) di -f -m
libverify.so`runtime.heapBitsSetType:
....
0x4327139 <+2361>: cmpl $0x20, %edi
0x432713c <+2364>: sbbl %eax, %eax
0x432713e <+2366>: sbbl %edx, %edx
0x4327140 <+2368>: movzbl (%r10), %ebx
0x4327144 <+2372>: andl $0x3, %ebx
0x4327147 <+2375>: orl $0x10, %ebx
-> 0x432714a <+2378>: movzbl (%rsi), %r8d
0x432714e <+2382>: movl %edi, %ecx
0x4327150 <+2384>: movl $0x33, %r9d
0x4327156 <+2390>: shll %cl, %r9d
0x4327159 <+2393>: andl %eax, %r9d
It looks like the heapAreana.bitmap
corresponding to this newly allocated memory p
is NULL
.
I could not find an efficient debugger on Catalina to further dig into this problem;
lldb
cannot set breakpoints;dlv
andgdb
cannot display symbols; Pls let me know if you have a working debugger on Catalina.
Then I tried to add many print
statements to the Go runtime and found:
runtime.mheap_
from the main executable's Go runtime.
And it could not find any records in mheap_.arenas[0][*]
corresponding the memory p
allocated via the shared library's runtime.mheap_
.But I still do not know why the shared library was accessing the wrong runtime.mheap_
.
I've tried to rewrite the executable and the shared library in C language, and the following scenarios all work well:
any thoughts?
A shared library built with -buildmode=c-shared
is intended to be used with a C program, not a Go program.
I don't know whether the Mach-O symbol visibility rules can support using -buildmode=c-shared
with a Go program.
Emmanual @odeke-em found that Go 1.11 gave a CGO error, not a segfault.
@networkimprov - Did you get this working by any chance?
@ianlancetaylor - IMHO, If golang is providing a way to build native shared library, then it does not matter, whether caller is written in Go, C, C++ or any other language, as long as caller follow the rules.
Unless we have strict symbol visibility control, it matters what language the caller is written, because a Go program and a Go shared library will define many symbols with the same names. Those symbols must be distinct, and not combined by the dynamic linker.
这个问题,你在dll的代码里面只要用到了接口,必报错
这个问题在go任何一个支持cgo的版本都会出现,包括最新的1.19
go version: go1.20.5 darwin/amd64
os: uname -a Darwin macbookdeMacBook-Pro.local 20.6.0 Darwin Kernel Version 20.6.0: Thu Jul 6 22:12:47 PDT 2023; root:xnu-7195.141.49.702.12~1/RELEASE_X86_64 x86_64
golang call .dylib from golang code.
this is .dylib is been golang generate.
this is Makefile
CGO_ENABLED=1 \
GOOS=darwin \
GOARCH=amd64 \
go build \
-buildmode=c-shared \
-o bin/darwin/*.dylib
fatal error: bad sweepgen in refill
goroutine 1 [running]:
runtime.throw({0x14ae9f7?, 0xc000666de0?})
/usr/local/go/src/runtime/panic.go:1047 +0x5d fp=0xc000666d80 sp=0xc000666d50 pc=0x1035b3d
runtime.(*mcache).refill(0x9c005b8, 0x0?)
/usr/local/go/src/runtime/mcache.go:157 +0x216 fp=0xc000666dc0 sp=0xc000666d80 pc=0x10167d6
runtime.(*mcache).nextFree(0x9c005b8, 0x5)
/usr/local/go/src/runtime/malloc.go:855 +0x85 fp=0xc000666e08 sp=0xc000666dc0 pc=0x100d3a5
runtime.mallocgc(0x4, 0x140b3e0, 0x1)
/usr/local/go/src/runtime/malloc.go:1017 +0x2c5 fp=0xc000666e70 sp=0xc000666e08 pc=0x100d805
reflect.unsafe_New(0xc0001c2840?)
/usr/local/go/src/runtime/malloc.go:1259 +0x27 fp=0xc000666e98 sp=0xc000666e70 pc=0x1064807
reflect.New({0x15546e8?, 0x140b3e0})
/usr/local/go/src/reflect/value.go:3194 +0x5f fp=0xc000666ec8 sp=0xc000666e98 pc=0x109b79f
github.com/ebitengine/purego.RegisterFunc.func1({0xc0001123f0?, 0x2?, 0x2?})
/Users/mac/wsp/gowork/pkg/mod/github.com/ebitengine/purego@v0.5.0/func.go:259 +0xada fp=0xc000667238 sp=0xc000666ec8 pc=0x13777ba
reflect.callReflect(0xc00053fc50, 0xc0006677a0, 0xc000667678, 0xc000667680)
/usr/local/go/src/reflect/value.go:772 +0x56d fp=0xc000667628 sp=0xc000667238 pc=0x109558d
reflect.callReflect(0xc00053fc50, 0xc0006677a0, 0xc000667678, 0xc000667680)
<autogenerated>:1 +0x4b fp=0xc000667658 sp=0xc000667628 pc=0x10a012b
reflect.makeFuncStub()
/usr/local/go/src/reflect/asm_amd64.s:47 +0x7a fp=0xc0006677a0 sp=0xc000667658 pc=0x109e79a
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?go env
Outputuname -a
OutputWhat did you do?
// #include
import "C"
import ( "encoding/hex" "strings"
)
//export Verify func Verify(serviceNameC C.char, keyC C.char) *C.char { serviceName := C.GoString(serviceNameC)
}
func main() {
}
package sec
import ( "encoding/hex" "fmt" )
var CryptoKey []byte
func InitWithKey(key []byte) { CryptoKey = key fmt.Println(hex.EncodeToString(key)) }
package main
// #cgo LDFLAGS: -lverify // #include </usr/local/lib/verify.h> import "C" import ( "fmt" "unsafe" )
func freeCString(cString *C.char) { C.free(unsafe.Pointer(cString)) }
func Init(serviceName string) { cServiceName := C.CString(serviceName) defer freeCString(cServiceName) key := C.CString("test") defer freeCString(key)
}
func main() { Init("my-service") }
fatal error: unexpected signal during runtime execution [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x41e745a]
goroutine 1 [running, locked to thread]: runtime.throw(0x40d653d, 0x2a) /usr/local/go/src/runtime/panic.go:1116 +0x72 fp=0xc0000439b0 sp=0xc000043980 pc=0x4030dd2 runtime: unexpected return pc for runtime.sigpanic called from 0x41e745a stack: frame={sp:0xc0000439b0, fp:0xc0000439e0} stack=[0xc000043000,0xc000044000) 000000c0000438b0: 0000000000000000 0000000000000000 000000c0000438c0: 0000000000000000 0000000000000000 000000c0000438d0: 0000000000000000 0000000000000000 000000c0000438e0: 0000000000000000 0000000000000000 000000c0000438f0: 0000000000000000 0000000000000000 000000c000043900: 0000000000000000 0000000000000000 000000c000043910: 0000000000000000 0000000000000000 000000c000043920: 0000000000000000 0000000000000000 000000c000043930: 0000000000000000 0000000000000000 000000c000043940: 0000000004030f97 <runtime.fatalthrow+87> 000000c000043950 000000c000043950: 000000000405a860 <runtime.fatalthrow.func1+0> 000000c000000180 000000c000043960: 0000000004030dd2 <runtime.throw+114> 000000c000043980 000000c000043970: 000000c0000439a0 0000000004030dd2 <runtime.throw+114> 000000c000043980: 000000c000043988 000000000405a7e0 <runtime.throw.func1+0> 000000c000043990: 00000000040d653d 000000000000002a 000000c0000439a0: 000000c0000439d0 0000000004044f2a <runtime.sigpanic+1130> 000000c0000439b0: <00000000040d653d 000000000000002a 000000c0000439c0: 0000000000000000 0000000000000000 000000c0000439d0: 000000c000043aa8 !00000000041e745a 000000c0000439e0: >0000000000000000 0000000000000000 000000c0000439f0: 0000000000000000 0000000000000000 000000c000043a00: 0000000000000000 0000000000000000 000000c000043a10: 0000000000000000 0000000000000000 000000c000043a20: 000802aaaa00aaaa 0000000000000034 000000c000043a30: 0000000000000020 0000000000000000 000000c000043a40: 0000000000000000 0000000000000000 000000c000043a50: 0000000000000000 0000000000203000 000000c000043a60: 0000000000203000 0000000000203000 000000c000043a70: 0000000000000000 0000000000000000 000000c000043a80: 0000000000000008 0000000000000000 000000c000043a90: 0000000000000000 000000c000043b38 000000c000043aa0: 000000000400d726 <runtime.mallocgc+790> 000000c000043b48 000000c000043ab0: 00000000041df53e 000000c000012200 000000c000043ac0: 0000000000000010 0000000000000010 000000c000043ad0: 0000000004281340 0000000000000680 runtime.sigpanic() /usr/local/go/src/runtime/signal_unix.go:679 +0x46a fp=0xc0000439e0 sp=0xc0000439b0 pc=0x4044f2a
goroutine 2 [force gc (idle)]: runtime.gopark(0x40d7b98, 0x417f670, 0x1411, 0x1) /usr/local/go/src/runtime/proc.go:304 +0xe0 fp=0xc000030fb0 sp=0xc000030f90 pc=0x40337f0 runtime.goparkunlock(...) /usr/local/go/src/runtime/proc.go:310 runtime.forcegchelper() /usr/local/go/src/runtime/proc.go:253 +0xb7 fp=0xc000030fe0 sp=0xc000030fb0 pc=0x40336a7 runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:1373 +0x1 fp=0xc000030fe8 sp=0xc000030fe0 pc=0x405da91 created by runtime.init.6 /usr/local/go/src/runtime/proc.go:242 +0x35
goroutine 18 [GC sweep wait]: runtime.gopark(0x40d7b98, 0x417f7a0, 0x140c, 0x1) /usr/local/go/src/runtime/proc.go:304 +0xe0 fp=0xc00002c7a8 sp=0xc00002c788 pc=0x40337f0 runtime.goparkunlock(...) /usr/local/go/src/runtime/proc.go:310 runtime.bgsweep(0xc00008e000) /usr/local/go/src/runtime/mgcsweep.go:70 +0x9c fp=0xc00002c7d8 sp=0xc00002c7a8 pc=0x4021a4c runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:1373 +0x1 fp=0xc00002c7e0 sp=0xc00002c7d8 pc=0x405da91 created by runtime.gcenable /usr/local/go/src/runtime/mgc.go:214 +0x5c
goroutine 19 [GC scavenge wait]: runtime.gopark(0x40d7b98, 0x417f760, 0x140d, 0x1) /usr/local/go/src/runtime/proc.go:304 +0xe0 fp=0xc00002cf78 sp=0xc00002cf58 pc=0x40337f0 runtime.goparkunlock(...) /usr/local/go/src/runtime/proc.go:310 runtime.bgscavenge(0xc00008e000) /usr/local/go/src/runtime/mgcscavenge.go:237 +0xd0 fp=0xc00002cfd8 sp=0xc00002cf78 pc=0x401ffa0 runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:1373 +0x1 fp=0xc00002cfe0 sp=0xc00002cfd8 pc=0x405da91 created by runtime.gcenable /usr/local/go/src/runtime/mgc.go:215 +0x7e
goroutine 3 [finalizer wait]: runtime.gopark(0x40d7b98, 0x41a8ca8, 0x1410, 0x1) /usr/local/go/src/runtime/proc.go:304 +0xe0 fp=0xc000030758 sp=0xc000030738 pc=0x40337f0 runtime.goparkunlock(...) /usr/local/go/src/runtime/proc.go:310 runtime.runfinq() /usr/local/go/src/runtime/mfinal.go:175 +0xa3 fp=0xc0000307e0 sp=0xc000030758 pc=0x4017773 runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:1373 +0x1 fp=0xc0000307e8 sp=0xc0000307e0 pc=0x405da91 created by runtime.createfing /usr/local/go/src/runtime/mfinal.go:156 +0x61 exit status 2