Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: darwin using -buildmode=c-shared so got runtime: unexpected return pc for runtime.sigpanic called from 0x41e745a #40131

Open
wangzz719 opened this issue Jul 9, 2020 · 4 comments

Comments

@wangzz719
Copy link

@wangzz719 wangzz719 commented Jul 9, 2020

What version of Go are you using (go version)?

$ go version
go version go1.14.4 darwin/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/wangzhizhao/Library/Caches/go-build"
GOENV="/Users/wangzhizhao/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GONOPROXY="*.byted.org,*.everphoto.cn"
GONOSUMDB="*.byted.org,*.everphoto.cn"
GOOS="darwin"
GOPATH="/Users/wangzhizhao/go"
GOPRIVATE="*.byted.org,*.everphoto.cn"
GOPROXY="https://go-mod-proxy.byted.org,https://goproxy.cn,https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.google.cn"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/wangzhizhao/go/src/goscripts/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/c5/gc9h916j1578f82zvg1hgxf40000gp/T/go-build852002820=/tmp/go-build -gno-record-gcc-switches -fno-common"
uname -a Output
$uname -a
Darwin wangzhizhaodeMacBook-Pro.local 18.7.0 Darwin Kernel Version 18.7.0: Mon Apr 27 20:09:39 PDT 2020; root:xnu-4903.278.35~1/RELEASE_X86_64 x86_64

What did you do?

  1. source code is the following two files:
    verify.go
package main

// #include <stdlib.h>
import "C"

import (
	"encoding/hex"
	"strings"

	"verify/sec"
)

//export Verify
func Verify(serviceNameC *C.char, keyC *C.char) *C.char {
	serviceName := C.GoString(serviceNameC)

	key := []byte(C.GoString(keyC))
	sec.InitWithKey(key)

	res := "res"
	return C.CString(strings.Join([]string{serviceName, res, hex.EncodeToString(key)}, "-"))
}

func main() {

}

sec/key.go

package sec

import (
	"encoding/hex"
	"fmt"
)

var CryptoKey []byte

func InitWithKey(key []byte) {
	CryptoKey = key
	fmt.Println(hex.EncodeToString(key))
}
  1. go build genrate c-shared .so
    go build -buildmode=c-shared -a -o libverify.so verify.go

  2. using libverify.so

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)

	cRes := C.Verify(cServiceName, key)
	defer freeCString(cRes)

	fmt.Println(C.GoString(cRes))
}

func main() {
	Init("my-service")
}

What did you expect to see?

no panic, and print out a string.

What did you see instead?

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
@wangzz719 wangzz719 changed the title Darwin using c-shared so got fatal error: bad sweepgen in refill Darwin using c-shared so got runtime: unexpected return pc for runtime.sigpanic called from 0x41e745a Jul 9, 2020
@odeke-em odeke-em changed the title Darwin using c-shared so got runtime: unexpected return pc for runtime.sigpanic called from 0x41e745a runtime: darwin using -buildmode=c-shared so got runtime: unexpected return pc for runtime.sigpanic called from 0x41e745a Jul 10, 2020
@odeke-em
Copy link
Member

@odeke-em odeke-em commented Jul 10, 2020

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

@luchsh
Copy link

@luchsh luchsh commented Jul 21, 2020

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 and gdb 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:

  • the initialization code of the shared library got executed.
  • but the shared library code was trying to access 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:

  • C-calls-Go
  • Go-calls-C
  • C-calls-C

any thoughts?

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jul 22, 2020

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.

@networkimprov
Copy link

@networkimprov networkimprov commented Jul 22, 2020

Emmanual @odeke-em found that Go 1.11 gave a CGO error, not a segfault.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.