go-kiss / monkey

Go语言猴子补丁框架
https://taoshu.in/go/monkey/
MIT License
119 stars 18 forks source link

关于 getg 的一些疑问 #16

Closed Ruomenger closed 11 months ago

Ruomenger commented 11 months ago

目前monkeygetg函数的实现在windows平台下是

mov r13,QWORD PTR gs:0x28
mov r12,QWORD PTR [r13]

在linux平台下的实现是

mov r12,QWORD PTR fs:0xfffffffffffffff8

我在 https://go.googlesource.com/go/+/refs/heads/dev.regabi/src/cmd/compile/internal-abi.md 和自己的测试中发现go使用r14寄存器 存储当前的goroutine指针,那么为何不能直接获取r14的值来用呢?

1696777792787

image

我将getg在windows和linux的实现修改为了

func getg() []byte {
    return []byte{
        // mov r12, r14
        0x4D, 0x89, 0xF4,
    }
}

都是可以正常跑通测试的,并不会有问题,那么之前的这种写法是有什么别的考虑吗?如果没有的话用这种方法应该可以统一win/linux(应该也包括intel版mac,但是m1芯片的mac是arm应该不行)的getg实现,且解决之前的windows平台下panic的问题。

image

@taoso FYI

taoso commented 11 months ago

这部分代码我是反汇编 go-tls 代码找到的,还专门写了篇博客记录过程^m2

我在第一篇文章^m1中也引用了 internal-abi,但没有注意到 R14 中保存了当前协程。

你这个方案在 macos 下也没问题,我同时测试了 go1.18 和 go1.21,确实优雅 👍 你来提 PR 吧

Ruomenger commented 11 months ago

好的