-
Notifications
You must be signed in to change notification settings - Fork 59
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
fatal error: unreachable method called. linker bug? #55
Comments
@devanwang 因为你编译的t.go不是一个main包,所以go build -x -n -v t.go 2>&1 | sed -n "/^# import config/,/EOF$/p" |grep -v EOF > importcfg 这个得到的信息是错的. |
正确的信息是类似这样的
|
@pkujhd 大佬,我把t.go的package改了main,cat importcfg结果如下:
然后重新编译t.o,执行loader还是同样的报错 |
给下你的运行环境和golang的版本 |
Linux version 5.4.119-1-tlinux4-0005 (root@VM_197_173_centos) (gcc version 8.3.1 20191121 (Red Hat 8.3.1-5) |
如果在t.go里调用reflect
会报错 Load error: unresolve external:reflect.(*rtype).FieldByIndex |
你的case可以在loader中注册掉这个interface暂时避免
|
加了这个不会报linker bug了,unresolve external:reflect.xxx还是会有 |
这个reflect的函数loader里没有使用,你需要注册 |
在t.go里只加了一行reflect.TypeOf(param),每次都报不同的错,没法加啊 我看原理会解析loader bin的symbols, 我在loader里同样加了reflect.TypeOf(param)代码,还是不行 |
Refelect 包会用到一系列的函数,都要注册,或者就在你的加载器里有类似的代码,会移动处理加载器里的符号 |
不是很懂,大佬能不能给个具体例子,针对t.go里的reflect.TypeOf函数,我要在loader写什么? |
就是你在loader里也调用过相应的函数,就会自动注册 |
这个不行,在loader里加了同样的reflect.TypeOf(param)还是会报如下错误: 大佬你那边可以试下 |
@pkujhd 查nm找到原因了,loader里的reflect.TypeOf被内联优化了,t.o的没有被内联,加上-gcflags -l就可以了,但这样编译器就禁止内联了,不知道有啥好办法没有 |
这个没啥办法,内联了要么你loader的时候重新提供一份,要么loader就是禁止inline的 |
@devanwang ,这个问题查了下,是因为loader中产生的type,由于连接优化,剔除了Intf.Print, 因此上在加载一个扩展的时候,两边的类型虽然名字相同但是实际类型却不一样,无法正确运行,如果你需要在runtime和dynamic library之间传递interface,那么需要使得两边的类型一致(即需要手动注册相应的函数,保证runtime里边产生的type是一样的). |
记录下这个case的调试信息:
以上是这个case所有需要relocate的列表, main.Test需要重定向type.github.com/pkujhd/goloader/examples/p.Intf,这个type已经在load中存在,但是对应的stuc.Print不存在,就会导致运行错误 记录信息: 可以采用-dynlink作为编译参数,这个参数是golang为plugin的模式添加的编译参数,会产生一个go.plugin.tabs的symbol来储存需要导出的函数,plugin模式用它来初始化moduledata的ptabEntry, 然后plugin模块读取这个array来产生导出的符号列表, 但是这个问题在goversion>=1.12的schedule这个case的时候会导致找不到符号runtime.gosched_m·f, 这个符号在runtime.a里,但是生成的loader里边没有,生成的.o里也没有,暂时无法处理;而不包含-dynlink的编译成的.o,runtime.gosched_m·f,这个符号就在当前的.o里. now blocking... |
I think this is an artefact of the main PR #66 adds a functionality to patch the first module's itabs to point at newly included method offsets if they're now available in a dynamic module, which prevents these I've made a separate branch here with this commit eh-steve@78fc98a demonstrating the solution. If you check out that branch and run either: cd ./examples/jit
go build .
./jit or (using old loader) cd ./examples/issue55/t/
go build -o t.o .
cd ../p/
go build -o p.o .
cd ../../loader
go build .
./loader -o ../issue55/t/t.o -o ../issue55/p/p.o -run "github.com/pkujhd/goloader/examples/issue55/t.Test" It should be working (without the main binary having registered any extra types!) |
hi, 大佬,下面是复现步骤:
在example下新建两个目录p和t,在p下新建p.go,在t下新建t.go
p.go:
t.go:
修改loader.go函数声明和调用:
在t目录中执行
go build -x -n -v t.go 2>&1 | sed -n "/^# import config/,/EOF$/p" |grep -v EOF > importcfg && go tool compile -importcfg importcfg t.go
,生成t.o文件在loader目录中执行
go build loader.go && ./loader -o ../t/t.o -run main.Test
,报错fatal error: unreachable method called. linker bug?The text was updated successfully, but these errors were encountered: