-
Notifications
You must be signed in to change notification settings - Fork 18k
plugin: tls handshake panic: unreachable method called. linker bug? #51621
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
Comments
A simpler reproduction:
---- main.go---- package main
import (
"demo2/pkg"
"fmt"
"plugin"
)
func main() {
p, err := plugin.Open("./plugin.so")
if err != nil {
panic(err)
}
s, err := p.Lookup("F")
if err != nil {
panic(err)
}
s.(func())() // Blocking Listen call
fmt.Println(pkg.T(1)) // Do something with tls.Config
} ----plugin.go---- package main
import "demo2/pkg"
func F() {
pkg.F()
} ---- pkg/pkg.go---- package pkg
func F() {
var v interface{} = new(T)
v.(I).m()
}
type I interface {
m()
}
type T int
func (*T) m() {} After using fatal error: unreachable method called. linker bug? goroutine 1 [running]: runtime.throw({0x7f25026dea85, 0xc000148000}) runtime/panic.go:1198 +0x71 fp=0xc000056eb0 sp=0xc000056e80 pc=0x7f2502645fd1 runtime.unreachableMethod() runtime/iface.go:563 +0x25 fp=0xc000056ed0 sp=0xc000056eb0 pc=0x7f250261dbe5 demo2/pkg.F(...) demo2/pkg/pkg.go:5 demo2.F() demo2/plugin.go:6 +0x48 fp=0xc000056f00 sp=0xc000056ed0 pc=0x7f25026d6568 main.main() demo2/main.go:20 +0x10d fp=0xc000056f80 sp=0xc000056f00 pc=0x51af6d runtime.main() runtime/proc.go:255 +0x227 fp=0xc000056fe0 sp=0xc000056f80 pc=0x48b5a7 runtime.goexit() runtime/asm_amd64.s:1581 +0x1 fp=0xc000056fe8 sp=0xc000056fe0 pc=0x4b6881 The type (*T) in host binary is: 00000000005296c0 : 5296c0: 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 ................ 5296d0: ff 0b 21 3b 09 08 08 36 28 57 54 00 00 00 00 00 ..!;...6(WT..... 5296e0: f0 14 56 00 00 00 00 00 c8 0a 00 00 00 00 00 00 ..V............. 5296f0: 00 48 52 00 00 00 00 00 58 17 00 00 01 00 00 00 .HR.....X....... 529700: 10 00 00 00 00 00 00 00 1d 00 00 00 e0 85 00 00 ................ 529710: ff ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00 ................ But in the plugin: 00000000001bc120 : 1bc120: 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 ................ 1bc130: ff 0b 21 3b 09 08 08 36 00 00 00 00 00 00 00 00 ..!;...6........ 1bc138: R_X86_64_64 runtime.memequal64·f@@Base 1bc140: 28 bd 1a 00 00 00 00 00 c0 0a 00 00 00 00 00 00 (............... 1bc140: R_X86_64_RELATIVE *ABS*+0x1abd28 1bc150: 00 00 00 00 00 00 00 00 20 17 00 00 01 00 00 00 ........ ....... 1bc150: R_X86_64_64 type.e1XyHGHH@@Base 1bc160: 10 00 00 00 00 00 00 00 22 00 00 00 a0 84 00 00 ........"....... 1bc170: 40 17 06 00 40 17 06 00 00 00 00 00 00 00 00 00 @...@........... Seems like the method M of *T in host binary is marked as unreacheble, so the ifn and tfn of it is "ff ff". |
Maybe reloc type R_METHODOFF should be mark as reachable for "DynlinkingGo". |
cc @golang/runtime |
meet same issue. |
@cherrymui probably has the most context on this. |
Thanks for report. When plugin is used, we already mark all exported methods reachable. But an unexported method could also be reachable from both the plugin and the host. We need to mark them as well. |
@cherrymui Thank you for the explanations |
Change https://go.dev/cl/393365 mentions this issue: |
Well, it's ingenious. Maybe we need a backport to 1.17 and 1.18? |
Backport issue(s) opened: #51736 (for 1.17), #51737 (for 1.18). Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases. |
Change https://go.dev/cl/397483 mentions this issue: |
Change https://go.dev/cl/397484 mentions this issue: |
When plugin is used, we already mark all exported methods reachable. However, when the plugin and the host program share a common package, an unexported method could also be reachable from both the plugin and the host via interfaces. We need to mark them as well. Fixes #51736. Updates #51621. Change-Id: I1a70d3f96b66b803f2d0ab14d00ed0df276ea500 Reviewed-on: https://go-review.googlesource.com/c/go/+/393365 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Than McIntosh <thanm@google.com> (cherry picked from commit 91631bc) Reviewed-on: https://go-review.googlesource.com/c/go/+/397484
When plugin is used, we already mark all exported methods reachable. However, when the plugin and the host program share a common package, an unexported method could also be reachable from both the plugin and the host via interfaces. We need to mark them as well. Fixes #51737. Updates #51621. Change-Id: I1a70d3f96b66b803f2d0ab14d00ed0df276ea500 Reviewed-on: https://go-review.googlesource.com/c/go/+/393365 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Than McIntosh <thanm@google.com> (cherry picked from commit 91631bc) Reviewed-on: https://go-review.googlesource.com/c/go/+/397483
Change https://go.dev/cl/467019 mentions this issue: |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Reproduced with go1.18rc1.
Not reproduced with go1.16.15
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
I build a plugin that calls http.ListenAndServeTLS(). The program that loads the plugin does something with a tls.Config{}.
Then I tried to make a tls connection. In this example, the code about the tls.Config in the main program is not called because the function loaded from the plugin is blocking.
Plugin:
Build plugin:
go build -buildmode=plugin -o plugin.so
Main file:
TLS connection:
openssl s_client -connect 127.0.0.1:4443
What did you expect to see?
No error. A successful connection.
What did you see instead?
> go run main.go
fatal error: unreachable method called. linker bug?
TraceThe text was updated successfully, but these errors were encountered: