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

plugin: crash on darwin/amd64 #17828

Closed
wendigo opened this issue Nov 7, 2016 · 12 comments
Closed

plugin: crash on darwin/amd64 #17828

wendigo opened this issue Nov 7, 2016 · 12 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@wendigo
Copy link

wendigo commented Nov 7, 2016

Please answer these questions before submitting your issue. Thanks!

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

go version devel +e017802 Sun Nov 6 20:11:48 2016 +0000 darwin/amd64

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

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/mateusz.gajewski/Desktop/Projects/"
GORACE=""
GOROOT="/usr/local/Cellar/go/HEAD-e017802/libexec"
GOTOOLDIR="/usr/local/Cellar/go/HEAD-e017802/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/43/1y0rrqr55zq3f8cj5wpkt1kmhc7r33/T/go-build192530039=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"

What did you do?

plugin.go:

package main
import "net/http"

func X() *http.Header {
	return &http.Header{}
}

host.go:

package main

import "plugin"

func main() {
	plugin.Open("main.so")
}

What did you expect to see?

plugin loaded without error

What did you see instead?

unexpected fault address 0xb01dfacedebac1e
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x1 addr=0xb01dfacedebac1e pc=0x505ee0c]

goroutine 1 [running]:
runtime.throw(0x406d4dc, 0x5)
	/usr/local/Cellar/go/HEAD-e017802/libexec/src/runtime/panic.go:596 +0x95 fp=0xc42004fa50 sp=0xc42004fa30
runtime.sigpanic()
	/usr/local/Cellar/go/HEAD-e017802/libexec/src/runtime/signal_unix.go:276 +0x28c fp=0xc42004faa0 sp=0xc42004fa50
panic: runtime error: slice bounds out of range
fatal error: panic on system stack
panic during panic

runtime stack:
panic(0x4060c20, 0x40a2de0)
	/usr/local/Cellar/go/HEAD-e017802/libexec/src/runtime/panic.go:420 +0x7d6

goroutine 1 [running]:
runtime.systemstack_switch()
	/usr/local/Cellar/go/HEAD-e017802/libexec/src/runtime/asm_amd64.s:268 fp=0xc42004f9f0 sp=0xc42004f9e8
runtime.dopanic(0x0)
	/usr/local/Cellar/go/HEAD-e017802/libexec/src/runtime/panic.go:579 +0x58 fp=0xc42004fa30 sp=0xc42004f9f0
runtime.throw(0x406d4dc, 0x5)
	/usr/local/Cellar/go/HEAD-e017802/libexec/src/runtime/panic.go:596 +0x95 fp=0xc42004fa50 sp=0xc42004fa30
runtime.sigpanic()
	/usr/local/Cellar/go/HEAD-e017802/libexec/src/runtime/signal_unix.go:276 +0x28c fp=0xc42004faa0 sp=0xc42004fa50
panic: runtime error: slice bounds out of range
fatal error: panic on system stack
stack trace unavailable
exit status 4
@wendigo
Copy link
Author

wendigo commented Nov 7, 2016

And another:

plugin.go:

package main

import "strings"

// does not need to be exported
var testVariable = strings.ToUpper("HELLO")

crashes with:

unexpected fault address 0xb01dfacedebac1e
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x1 addr=0xb01dfacedebac1e pc=0x504e2fb]

goroutine 1 [running]:
runtime.throw(0x406d4dc, 0x5)
    /usr/local/Cellar/go/HEAD-e017802/libexec/src/runtime/panic.go:596 +0x95 fp=0xc42004fbb8 sp=0xc42004fb98
runtime.sigpanic()
    /usr/local/Cellar/go/HEAD-e017802/libexec/src/runtime/signal_unix.go:276 +0x28c fp=0xc42004fc08 sp=0xc42004fbb8
strings.Map(0x5046e80, 0x506a736, 0x5, 0x1, 0xc42004fce8)
    /usr/local/Cellar/go/HEAD-e017802/libexec/src/strings/strings.go:393 +0x9b fp=0xc42004fc90 sp=0xc42004fc08
strings.ToUpper(0x506a736, 0x5, 0x0, 0x0)
    /usr/local/Cellar/go/HEAD-e017802/libexec/src/strings/strings.go:447 +0x41 fp=0xc42004fcc8 sp=0xc42004fc90
invalid spdelta type..eq.runtime.uncommontype 0x404fb60 0x504e7fc 0x2541c -1
type..eq.runtime.uncommontype(0x500, 0x0, 0x0, 0xc42004ff0800, 0x4052b6100, 0x450000000, 0x450000000, 0xc42000e01000, 0x504e79000, 0x500, ...)
    ?:0 +0xffec9c fp=0xc42004fccf sp=0xc42004fcc8

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /usr/local/Cellar/go/HEAD-e017802/libexec/src/runtime/asm_amd64.s:2184 +0x1
exit status 2

Probably reason why first case (with import net/http.Header) crashes is exactly the same as 2nd case (I've copied net/http/header.go and distilled come with this case)

@wendigo wendigo changed the title plugin - crash on darwin/amd64 plugin: crash on darwin/amd64 Nov 7, 2016
@quentinmit quentinmit added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Nov 7, 2016
@quentinmit quentinmit added this to the Go1.8 milestone Nov 7, 2016
@crawshaw
Copy link
Member

Does import "C" in the plugin resolve this?

@crawshaw
Copy link
Member

I can reproduce this now on darwin/amd64. The plugin:

package main

// // nothing
import "C"

func F(f func()) {
    f()
}

func g() {}

func init() {
    F(g)
}

Will crash on plugin.Open:

fatal error: fault
[signal SIGSEGV: segmentation violation code=0x1 addr=0xb01dfacedebac1e pc=0x5048857]

goroutine 1 [running]:
runtime.throw(0x40cfed4, 0x5)
    /Users/crawshaw/go/src/runtime/panic.go:596 +0x95 fp=0xc42004fc50 sp=0xc42004fc30
runtime.sigpanic()
    /Users/crawshaw/go/src/runtime/signal_unix.go:276 +0x28c fp=0xc42004fca0 sp=0xc42004fc50
plugin/unnamed-06967b3c2cb9b2f422ec9fbcdcc9240020630896.F(0x5048870)
    /Users/crawshaw/plugin.go:7 +0x17 fp=0xc42004fca8 sp=0xc42004fca0
plugin/unnamed-06967b3c2cb9b2f422ec9fbcdcc9240020630896.init.1()
    /Users/crawshaw/plugin.go:13 +0x2d fp=0xc42004fcc0 sp=0xc42004fca8
plugin/unnamed-06967b3c2cb9b2f422ec9fbcdcc9240020630896.init()
    command-line-arguments/_obj/_cgo_import.go:4 +0x3d fp=0xc42004fcc8 sp=0xc42004fcc0
plugin.open(0x40d053c, 0x9, 0x0, 0x0, 0x0)
    /Users/crawshaw/go/src/plugin/plugin_dlopen.go:96 +0x933 fp=0xc42004ff08 sp=0xc42004fcc8
plugin.Open(0x40d053c, 0x9, 0x0, 0x0, 0x3)
    /Users/crawshaw/go/src/plugin/plugin.go:30 +0x35 fp=0xc42004ff40 sp=0xc42004ff08
main.main()
    /Users/crawshaw/host.go:9 +0x3a fp=0xc42004ff88 sp=0xc42004ff40
runtime.main()
    /Users/crawshaw/go/src/runtime/proc.go:185 +0x20a fp=0xc42004ffe0 sp=0xc42004ff88
runtime.goexit()
    /Users/crawshaw/go/src/runtime/asm_amd64.s:2184 +0x1 fp=0xc42004ffe8 sp=0xc42004ffe0

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /Users/crawshaw/go/src/runtime/asm_amd64.s:2184 +0x1
exit status 2

@crawshaw
Copy link
Member

While off on other projects, it looks like I have forgotten a lot of how the darwin port works. Running otool -Sv plugin.so shows no dynamic relocations, so I don't understand how the plugin can hope to refer to the g funcsym via MOVQ xyz(IP):

plugin.go:13    0x4889d 488b0524cc0100          MOVQ 0x1cc24(IP), AX
plugin.go:13    0x488a4 48890424                MOVQ AX, 0(SP)
plugin.go:13    0x488a8 e893ffffff              CALL _plugin/unnamed-....F(SB)     

I don't have many spare moments to work on this over the next month, so we may have to pull plugin support on OS X from 1.8.

@crawshaw
Copy link
Member

OK, one more observation. While I cannot remember how that PC-relative MOVQ works, the same code works in -buildmode=c-shared on darwin, and generates:

libgo.go:21     0x4f62a 488d05f7e40100          LEAQ 0x1e4f7(IP), AX                    
libgo.go:21     0x4f631 48890424                MOVQ AX, 0(SP)                          
libgo.go:21     0x4f635 e886000000              CALL main.F(SB)                         

So this problem could be more straightforward than some dynamic relocation mess.

@crawshaw
Copy link
Member

OK, not luck. This snippet is being mis-handled on darwin:

    0x001d 00029 (plugin.go:10) MOVQ    "".g·f@GOT(SB), AX
    0x0024 00036 (plugin.go:10) MOVQ    AX, (SP)
    0x0028 00040 (plugin.go:10) PCDATA  $0, $0

Unfortunately -dynlink on darwin is new for the plugin mode, so it could be anything. I'll try to find some more time for this next weekend. If I don't come up with anything, I'll pull plugin support on darwin.

@wendigo
Copy link
Author

wendigo commented Nov 12, 2016

Sad to hear that @crawshaw

@crawshaw
Copy link
Member

cc @minux @mwhudson who might be able to guess at the problem.

@mwhudson
Copy link
Contributor

The generated code looks fine, but definitely depends on the dynamic linker creating and filling out a GOT at 0x1cc24(%rip). IIRC, on ELF the external linker does that for you when it sees a R_X86_64_GOTPCREL relocation, maybe you need to do something else for macho? I don't know much of anything about how macho works though.

@crawshaw
Copy link
Member

@mwhudson thanks, for some reason I had just been assuming the GOT was fine. Looks like it wasn't, we were relocating to the outer "go.func.*" symbol in the GOT instead of the specific funcsym.

CL 33211 fixes that problem, and might fix this entire issue. But I'll keep it open for now just in case.

@gopherbot
Copy link

CL https://golang.org/cl/33211 mentions this issue.

gopherbot pushed a commit that referenced this issue Nov 16, 2016
To generate the correct section offset the shared code path for
R_CALL, R_PCREL, and R_GOTPCREL on darwin when externally linking
walks up the symbol heirarchy adding the differences. This is fine,
except in the case where we are generating a GOT lookup, because
the topmost symbol is left in r.Xsym instead of the symbol we are
looking up. So all funcsym GOT lookups were looking up the outer
"go.func.*" symbol.

Fix this by separating out the R_GOTPCREL code path.

For #17828 (and may fix it).

Change-Id: I2c9f4d135e77c17270aa064d8c876dc6d485d659
Reviewed-on: https://go-review.googlesource.com/33211
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
@crawshaw
Copy link
Member

Closing with the hope that CL 33211 takes care of it. If it doesn't, please reopen this.

@golang golang locked and limited conversation to collaborators Nov 16, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants