From f06e564be90f0dc96efc0c874522aa3d0becf70e Mon Sep 17 00:00:00 2001 From: pplonepiece Date: Sun, 22 Jul 2018 23:38:24 +0800 Subject: [PATCH] =?UTF-8?q?ch3-07=20=E6=8B=BC=E5=86=99=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ch3-asm/ch3-07-goroutine-id.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ch3-asm/ch3-07-goroutine-id.md b/ch3-asm/ch3-07-goroutine-id.md index 03e30ed..89a2b15 100644 --- a/ch3-asm/ch3-07-goroutine-id.md +++ b/ch3-asm/ch3-07-goroutine-id.md @@ -167,7 +167,7 @@ var g_goid_offset = func() int64 { 枚举和暴力穷举虽然够直接,但是对于正在开发中的未发布的Go版本支持并不好,我们无法提前知晓开发中的某个版本的goid成员的偏移量。 -如果是在runtime包内部,我们可以通过`unsafe.OffsetOf(g.gois)`直接获取成员的偏移量。也可以通过反射获取g结构体的类型,然后通过类型查询某个成员的偏移量。因为g结构体是一个内部类型,Go代码无法从外部包获取g结构体的类型信息。但是再Go汇编语言中,我们是可以看到全部的符号的,因此理论上我们也可以获取g结构体的类型信息。 +如果是在runtime包内部,我们可以通过`unsafe.OffsetOf(g.goid)`直接获取成员的偏移量。也可以通过反射获取g结构体的类型,然后通过类型查询某个成员的偏移量。因为g结构体是一个内部类型,Go代码无法从外部包获取g结构体的类型信息。但是在Go汇编语言中,我们是可以看到全部的符号的,因此理论上我们也可以获取g结构体的类型信息。 在任意的类型被定义之后,Go语言都会为该类型生成对应的类型信息。比如g结构体会生成一个`type·runtime·g`标识符表示g结构体的值类型信息,同时还有一个`type·*runtime·g`标识符表示指针类型的信息。如果g结构体带有方法,那么同时还会生成`go.itab.runtime.g`和`go.itab.*runtime.g`类型信息,用于表示带方法的类型信息。 @@ -194,7 +194,7 @@ TEXT ·getg(SB), NOSPLIT, $32-16 RET ``` -其中AX寄存器对应g指针,BX寄存器对应g结构体的类型。然后通过runtime·convT2E函数将类型转为接口。因为我们使用的不是g结构体指针类型,因此返回的接口表示的g结构体值类型。理论上我们也可以构造g指针类型的接口,但是因为Go汇编语言的限制,我们无法`type·*runtime·g`标识符。 +其中AX寄存器对应g指针,BX寄存器对应g结构体的类型。然后通过runtime·convT2E函数将类型转为接口。因为我们使用的不是g结构体指针类型,因此返回的接口表示的g结构体值类型。理论上我们也可以构造g指针类型的接口,但是因为Go汇编语言的限制,我们无法使用`type·*runtime·g`标识符。 基于g返回的接口,就可以容易获取goid了: