栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

golang反编译

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

golang反编译

Go语言的defer是一个很方便的机制,能够把某些函数调用推迟到当前函数返回前才实际执行。我们可以很方便的用defer关闭一个打开的文件、释放一个Redis连接,或者解锁一个Mutex。而且Go语言在设计上保证,即使发生panic,所有的defer调用也能够被执行。不过多个defer函数是按照定义顺序倒序执行的。 我们在公众号有一篇文章:

【Golang】脱胎换骨的defer​mp.weixin.qq.com

内容有点儿多,篇幅有点儿长,所以在这里我们打算拆分成四篇文章,每一篇专注一两个主要问题,可能会好消化些吧~

(一)“ defer如何延迟,因何倒序?”

(二)“ defer函数怎样传参?”

(三)“ defer+闭包,再多套几层,你还hold住吗?”

(四)“ 都说defer1.12性能有坑,那坑从何来?又该怎么填?”

func f1() {
    defer A()
    // code to do something
}

像这样一段代码,在Go1.12中编译后的伪指令是这样的(源码结合反编译整理出的伪代码,帮助理解~_~):

func f1() {
    r := runtime.deferproc(0, A) // 经过recover返回时r为1,否则为0
    if r > 0 {
        goto ret
    }
    // code to do something
    runtime.deferreturn()
    return
ret:
    runtime.deferreturn()
}

其中与defer指令相关的有两个部分。第一部分是deferproc,它负责保存要执行的函数信息,我们称之为defer“注册”。

func deferproc(siz int32, fn *funcval)

从函数原型来看,deferproc函数有两个参数,第一个是被注册的defer函数的参数加返回值共占多少字节;第二个参数是一个runtime.funcval结构体的指针,也就是一个Function Value。对Function Value感兴趣,可以看看这个:

网页链接​mp.weixin.qq.com

与defer指令相关的第二部分就是deferreturn,它被编译器插入到函数返回以前调用,负责执行已经注册的defer函数。所以defer函数之所以能延迟到函数返回前执行,就是因为先注册,后调用。

再来看看defer函数为什么会倒序执行。defer注册信息会保存到defer链表。每个goroutine在运行时都对应一个runtime.g结构体,其中有一个_defer字段,保存的就是defer链表的头指针。

deferproc新注册的defr信息会添加到链表头。deferreturn执行时也从链表头开始,所以defer才会表现为倒序执行。

理解了这些,就可以继续细化,看看defer注册时保存了什么信息,defer链表中每个元素究竟是什么结构了。

type _defer struct {
    siz       int32
    started   bool
    sp        uintptr // sp at time of defer
    pc        uintptr
    fn        *funcval
    _panic    *_panic // panic that is running defer
    link      *_defer
 }

siz:由deferproc第一个参数传入,就是defer函数参数加返回值的总大小。这段空间会直接分配在_defer结构体后面,用于在注册时保存给defer函数传入的参数,并在执行时直接拷贝到defer函数的调用者栈上。

started :标识defer函数是否已经开始执行;

sp:就是注册defer函数的函数栈指针;

pc:是deferproc函数返回后要继续执行的指令地址;

fn:由deferproc的第二个参数传入,也就是被注册的defer函数;

_panic:是触发defer函数执行的panic指针,正常流程执行defer时它就是nil;

link:自然是链到之前注册的那个_defer结构体。

网页链接​mp.weixin.qq.com

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/965585.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号