xgo: golang基于-toolexec实现猴子补丁

注: 转载请注明出处, 原文链接。

概述

在这篇博客中,我将详细介绍 xgo 的实现细节。

如果你不知道,xgo 项目位于 https://github.com/xhd2015/xgo。

它的作用很简单,就是在每个 Go 函数的开头添加拦截器,从而引入了所谓的 Trap 概念,然后在此基础上引入了其他功能,比如 MockPatchTrace

什么是 Trap?

Trap 是插入到函数体开头的一段代码。以一个名为 greet 的函数为例:

func greet(s string) string {return "hello " + s
}

经过xgo的处理后,编译器看到的代码将变为:

import "runtime"func greet(s string) (r0 string){stop, post := runtime.__xgo_trap(greet, &s, &r0)if stop {return}defer post()return "hello " +s
}

这两者的差异可以通过下面的图表来可视化:
在这里插入图片描述

如图所示,一旦函数被调用,它的控制流首先转移到 Trap,然后一系列拦截器将根据其目的检查当前调用是否应该被Mock、修改、记录或停止。

这个想法很简单,但也引发了一些问题:

  • 编译器如何看到插桩后的代码?
  • import runtime 是什么?

这两个问题反映了 xgo 的两个基本部分:编译器插桩和运行时插桩。

让我们先看看第一个问题。

编译器如何看到插桩后的代码?

为了让编译器看到与其原始源代码不同的代码,中间必须发生某种事情。

有趣的是,go build 有一个名为-toolexec的标志:

$ go help build
...
-toolexec 'cmd args'a program to use to invoke toolchain programs like vet and asm.For example, instead of running asm, the go command will run'cmd args /path/to/asm <arguments for asm>'.The TOOLEXEC_IMPORTPATH environment variable will be set,matching 'go list -f {{.ImportPath}}' for the package being built.
...

如果你搜索 go toolexec,甚至有一个示例:https://go.dev/src/cmd/go/testdata/script/toolexec.txt。

简而言之,-toolexec 标志允许用户拦截 go 调用的每个 compilelink 命令,并根据需要执行某种插桩,如下图所示:
在这里插入图片描述
请注意,当你在 go build 中添加 -toolexec=my_tool 标志时,它不会直接调用 compile argslink args,而是将这些调用转发给 my_tool <cmd> args

因此,xgo 利用这个标志来拦截 compile 命令,将所有的编译转发到增强后的编译器。

然后,增强后的编译器将在每个函数中插入这些Trap调用,为运行时在实际调用之前捕获函数调用提供机会。

import runtime 是什么?

现在,编译器已经为我们添加了Trap调用,我们如何知道需要进行什么样的检查?

我们不能让每个包都依赖于 xgo,因为它们可能并不需要它。

好在 runtime 也被插桩了,将调用转发给 xgo。因为在 Go 中,每个包都隐式依赖于 runtime 包。控制流程如下图所示:
在这里插入图片描述

这实际上是一种依赖注入。这样一来,用户的代码就不必显式依赖xgo。

上述代码可以在 runtime/trap_runtime/xgo_trap.go 和 runtime/trap/trap.go 中找到。

为了使Trap可扩展,xgo 引入了一个名为 interceptor 的概念。它具有以下签名:

type Interceptor struct {Pre  func(ctx context.Context, f *core.FuncInfo, args core.Object, result core.Object) (data interface{}, err error)Post func(ctx context.Context, f *core.FuncInfo, args core.Object, result core.Object, data interface{}) error
}

一个 interceptor 由两个子函数组成,称为 PrePost

  • Pre 在函数逻辑之前调用,
  • Post 在函数逻辑之后使用 defer 语句调用。

总结

让我们总结一下我们所讨论的内容。

当你运行 xgo test ./ 时,它会执行以下操作:

  1. 找到 GOROOT,
  2. 将 GOROOT 复制到 ~/.xgo/go-instruments/GOROOT 以准备进行插桩,
  3. 对 ~/.xgo/go-instruments/GOROOT 进行补丁,包括编译器和运行时,
  4. 构建插桩的编译器,
  5. 使用额外的标志调用 go build:go build -toolexec=exec_tool ./
  6. exec_tool 然后将所有编译命令转发给插桩的编译器,
  7. 一旦所有编译完成,go 调用 link 生成可执行文件,你就得到了一个插桩的二进制文件!

优点和缺点

因此,xgo 从上述机制中获得了优点和缺点。
优点:

  • 并发安全:它不会替换需要修改全局地址的函数,因此每个 goroutine 可以设置自己的拦截器并单独删除它们,
  • 兼容性:它重写源代码而不是架构指令,因此与操作系统和架构无关,
  • 可扩展性:它提供了通用的拦截器,因此它的用途不仅限于模拟,你可以借鉴 GRPC 拦截器的所有用途,比如已经实现的追踪、缓存、日志记录等…

缺点:

  • 用户需要安装 xgo 才能启用陷阱功能。

感谢阅读,xgo的核心实现已经在上面全部介绍了。你对此有什么看法?请在这里留下评论,让我们一起讨论吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/302411.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

吴恩达深度学习 (week1,2)

文章目录 1、神经网络监督学习2、深度学习兴起原因3、深度学习二元分类4、深度学习Logistic 回归5、Logistic 回归损失函数6、深度学习梯度下降法7、深度学习向量法8、Python 中的广播9、上述学习总结10、大作业实现:rocket::rocket:&#xff08;1&#xff09;训练初始数据&…

Android 关于apk反编译d2j-dex2jar classes.dex失败的几种方法

目录 确认路径正确直接定位到指定目录确定目录正确&#xff0c;按如下路径修改下面是未找到相关文件正确操作 确认路径正确 &#xff0c;即d2j-dex2jar和classes.dex是否都在一个文件夹里&#xff08;大部分的情况都是路径不正确&#xff09; 直接定位到指定目录 路径正确的…

2024年32款数据分析工具分五大类总览

数据分析工具在现代商业和科学中扮演着不可或缺的角色&#xff0c;为组织和个人提供了深入洞察和明智决策的能力。这些工具不仅能够处理大规模的数据集&#xff0c;还能通过强大的分析和可视化功能揭示隐藏在数据背后的模式和趋势。数据分析工具软件主要可以划分为以下五个类别…

2024年抖音小店还有机会吗?多年小店商家,带来最新判断!

大家好&#xff0c;我是电商糖果 糖果做电商有7年时间了&#xff0c;从2020年开始做抖音小店&#xff0c;现在已经经营了多家小店。 关于抖音小店的热度这几年一直居高不下&#xff0c;说实话几乎每天都有不少朋友找糖果咨询&#xff0c;2024年抖音小店还有机会吗&#xff1f…

JS 表单验证

点击注册的时候&#xff0c;渲染出来&#xff0c;验证码是自动获取出来的 html&#xff1a; <div class"div1">用户名<input type"text" id"yhm"><span id"span1"></span><br>密码<input type"…

一起学习python——基础篇(10)

前言&#xff0c;Python 是一种面向对象的编程语言。以前大学读书的时候经常开玩笑说的一句话“如果没有对象&#xff0c;就new一个”。起因就是编程老师上课时经常说一句“首先&#xff0c;我们new一个对象”。 今天讲一下python的类和对象。 类是什么&#xff1f;它是一种用…

外包干了25天,技术退步明显.......

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入杭州某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…

【运输层】TCP 的可靠传输是如何实现的?

目录 1、发送和接收窗口&#xff08;滑动窗口&#xff09; &#xff08;1&#xff09;滑动窗口的工作流程 &#xff08;2&#xff09;滑动窗口和缓存的关系 &#xff08;3&#xff09;滑动窗口的注意事项 2、如何选择超时重传时间 &#xff08;1&#xff09;加权平均往返…

爬虫 BeautifulSoup模块

爬虫 BeautifulSoup模块 【一】介绍 【1】说明 BeautifulSoup库是python的一个第三方库&#xff0c;主要用于处理HTML和XML文档他提供了一些简单的、python式的函数来解析、导航、搜索以及修改分析树&#xff0c;使得从网页抓取的数据变得简单高效BeautifulSoup自动将输入文…

ctfshow web入门 命令执行 web53--web77

web53 日常查看文件 怎么回事不让我看十八 弄了半天发现并不是很对劲&#xff0c;原来我发现他会先回显我输入的命令再进行命令的回显 ?cnl${IFS}flag.php||web54 绕过了很多东西 基本上没有什么命令可以用了但是 grep和?通配符还可以用 ?cgrep${IFS}ctfshow${IFS}???…

BFS宽度优先搜索例题(蓝桥杯)——逃跑的牛

问题描述&#xff1a; 农夫John的一头牛逃跑了&#xff0c;他想要将逃跑的牛找回来。现假设农夫John和牛的位置都在一条直线上&#xff0c;农夫John的初始位置为N&#xff08;0≤N≤100,000&#xff09;&#xff0c;牛的初始位置为K&#xff08;0≤K≤100,000&#xff09;。农夫…

R语言数据操纵:常用函数

目录 处理循环的函数 lapply函数 apply函数 mapply函数 tapply函数 split函数 排序的函数 sort函数与order函数 总结数据信息的函数 head函数与tail函数 summary函数 str函数 table函数 any函数 all函数 xtab函数 object.size函数 这篇文章主要介绍R语言中处理…

APP测试面试题详解

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、基础篇 1、请介绍一下&#xff0c;APP测试流程&#xff1f…

【算法统治世界】动态规划 个人笔记总结

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《数据结构与算法&#xff1a;初学者入门指南》&#x1f4d8;&am…

分布式主键ID生成策略

业务系统对分布式ID的要求 唯一性&#xff1a;在分布式系统中&#xff0c;每个节点都需要生成唯一的标识符来确保数据的唯一性。传统的单点生成ID方式无法满足分布式环境下的需求&#xff0c;而分布式ID能够在整个系统中保证每个节点生成的ID都是唯一的。 顺序性&#xff1a;某…

CSS设置网页颜色

目录 前言&#xff1a; 1.颜色名字&#xff1a; 2.十六进制码&#xff1a; 3.RGB&#xff1a; 4.RGBA&#xff1a; 5.HSL&#xff1a; 1.hue&#xff1a; 2.saturation&#xff1a; 3.lightness&#xff1a; 6.HSLA&#xff1a; 前言&#xff1a; 我们在电脑显示器&…

Linux 多线程

目录 初识线程 线程的概念 Linux下的线程 线程优缺点 线程控制 线程创建 线程终止 线程等待 线程分离 线程取消 其它 线程互斥 互斥的概念 互斥锁的使用 锁的本质 线程同步 线程同步的概念 条件变量的概念 条件变量的使用 信号量 信号量的概念 信号量接口…

007 CSS的继承和层叠 元素特性

文章目录 CSS属性的继承CSS属性的层叠选择器的权重 HTML元素的类型编写HTML注意事项元素隐藏方法CSS属性-overflowCSS样式不生效可能原因 CSS属性的继承 如果一个属性具备继承性&#xff0c;那么在该元素上设置后&#xff0c;它的后代元素都可以继承这个属性 如果后代元素自己…

如何将平板或手机作为电脑的外接显示器?

先上官网链接&#xff1a;ExtensoDesk 家里有一台华为平板&#xff0c;自从买回来以后除了看视频外&#xff0c;基本没什么作用&#xff0c;于是想着将其作为我电脑的第二个屏幕&#xff0c;提高我学习办公的效率&#xff0c;废物再次利用。最近了解到华为和小米生态有多屏协同…

android11 SystemUI入門之KeyguardPatternView解析

view层级树为&#xff1a; 被包含在 keyguard_host_view.xml中 。 <?xml version"1.0" encoding"utf-8"?> <!-- This is the host view that generally contains two sub views: the widget viewand the security view. --> <com.andro…