惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

PCI Perspectives
PCI Perspectives
Microsoft Security Blog
Microsoft Security Blog
MongoDB | Blog
MongoDB | Blog
T
The Blog of Author Tim Ferriss
罗磊的独立博客
人人都是产品经理
人人都是产品经理
The Cloudflare Blog
Engineering at Meta
Engineering at Meta
Y
Y Combinator Blog
宝玉的分享
宝玉的分享
Recorded Future
Recorded Future
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
月光博客
月光博客
Recent Announcements
Recent Announcements
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Apple Machine Learning Research
Apple Machine Learning Research
T
Threatpost
The GitHub Blog
The GitHub Blog
M
MIT News - Artificial intelligence
Scott Helme
Scott Helme
P
Palo Alto Networks Blog
T
Tenable Blog
P
Privacy International News Feed
V
Visual Studio Blog
F
Fortinet All Blogs
酷 壳 – CoolShell
酷 壳 – CoolShell
I
Intezer
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
AI
AI
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
S
Security Affairs
S
SegmentFault 最新的问题
C
Cisco Blogs
博客园 - 聂微东
MyScale Blog
MyScale Blog
V
Vulnerabilities – Threatpost
量子位
T
The Exploit Database - CXSecurity.com
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Security Latest
Security Latest
P
Proofpoint News Feed
阮一峰的网络日志
阮一峰的网络日志
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Troy Hunt's Blog
T
Tailwind CSS Blog
Stack Overflow Blog
Stack Overflow Blog
云风的 BLOG
云风的 BLOG
A
About on SuperTechFans
The Last Watchdog
The Last Watchdog

See you soon

试试将文章版本化管理吧 | See you soon 使用 Quadlet 将 Podman 中的 Postgres 当作 systemd 服务运行 | See you soon 大他者,那个无时无刻都在盯着你的东西 | See you soon Laws of Software Engineering,软件工程定律 | See you soon 浅记多因素身份认证 | See you soon Linux 内核中的度量单位 | See you soon 重置 GPG 智能密钥 | See you soon 向 NAS 引入 samba | See you soon 无法重复键入的 Fcitx5 | See you soon ZFS 降级事故 | See you soon 记被 XanMod Kernel 和 AppArmor 联合坑的一次踩坑 | See you soon agent 的 skill 与 toolcall | See you soon 记一次服务器被挂恶意挖矿二进制 | See you soon 活着的 Arc | See you soon 令 acme.sh 使用 Cloudflare 的 DNS API 签发与续签证书 | See you soon 于 Tokio 中卸载 CPU Bound 任务 | See you soon 如我所见,梦破碎的时候 | See you soon 74LS 家族手册 | See you soon JDK Projects 备忘录 | See you soon 关于历史 | See you soon 用 curl 下载 OnePlus 的 ROM | See you soon 实用命令切片 | See you soon 再见,Oh My Zsh。 | See you soon 你不应该复用 strings.Builder | See you soon 博客的明日 | See you soon 被 AppArmor 击杀的 Dockge | See you soon AI 时代的自我 | See you soon 支持删除的布隆过滤器 | See you soon 基于栈的虚拟机与基于寄存器的虚拟机 | See you soon RVA23 包含了什么 | See you soon Rust 的边界检查是否已经有很大的进步 | See you soon 使用 Rust 编写操作系统:Barebones | See you soon 使用 Rust 编写操作系统:引言 | See you soon 编译器笔记:rope | See you soon 编译器笔记:CST | See you soon Paradoxical 札记 | See you soon 简单的相似去重算法(基于向量) | See you soon 更加现代的 PaperMC Minecraft 插件设计指南 | See you soon 简单的 CFG 语法分析方法 | See you soon 简单地使用 Caddy 实现 CORS 配置 | See you soon 让 OpenCV 可以被静态链接 | See you soon 图片搜索笔笺 | See you soon 电路板设计笔记-保护 | See you soon 使用 Rust 实现 SnowflakeId | See you soon 农夫乐事 FaQ 启示 | See you soon 遗传学定律的代码实现 | See you soon EN:The Journey of Rust and Procps | See you soon ZH:Rust 与 Procps 之旅 | See you soon 使用 debootstrap 与 schroot 构建一个纯净环境 | See you soon GPG添加新的用户信息 | See you soon GSoC2024 笔记:使用 Rust 重新实现 procps | See you soon JWT 小册 | See you soon 使用密钥登录 SSH | See you soon Guava:Cache | See you soon 编译器笔记:增量编译 | See you soon Gradle秘境:添加一个类似modCompileOnly的依赖块 | See you soon Minecraft:原始经济系统设计简述 | See you soon TinyRemapper笔记 | See you soon MicroOS:进阶 | See you soon MicroOS:起步 | See you soon Swapfile 指北 | See you soon GPG 物理密钥的安装与密钥的迁移 | See you soon 用GPG签名告诉大家这就是我的提交 | See you soon DFS:深度优先搜索 | See you soon 文章翻译:从init.vim到init.lua | See you soon 目录遍历攻击 | See you soon 如何挂载.img文件,以及如何使用QEMU模拟arm64环境 | See you soon 在树莓派上编译 OpenCV | See you soon 关于卸载BlueStacks后遇到的问题 | See you soon
使用 Rust 实现拓展系统札记 | See you soon
Krysztal Huang · 2024-09-18 · via See you soon

Rust 在生产上的优势十分明显了,极高的性能和极致的资源体验。

但是对于我而言,总是觉得少了些什么——拓展系统。

方案选择

与我熟悉的 JVM 平台不同,JVM 平台通过在虚拟机内运行时链接的方式实现稳定的 ABI。这是稳定性和可控性极高的实践,很符合 JVM 的特性。

而 Rust 所属的 Native 平台需要通过系统的链接器——比如 ld 等——这涉及到平台提供的动态链接功能。

但是除此之外,在 Rust 生态里,甚至是新的编程语言生态里,产生了一种新的拓展架构——加载 wasm 文件作为拓展。

综上所述,我们有两种可以考虑的架构:

  • 原生平台拓展:通过加载 sodylibdll 等动态库来实现拓展
  • wasm 平台拓展:通过加载 wasm 文件到 wasm 运行时,通过运行时获取拓展能力

接下来,我们将深入了解两种插件平台的实现上的区别。

原生平台

原生平台实现需要依赖编译器的 ABI 稳定,但是新时代的原生语言(Rust,Go,Crystal 等)基本上都没有稳定的 ABI,所以需要依赖 C 的稳定的 ABI 来曲线救国

但有个例外,Rust 平台存在 abi_stable 这个 crate,因此我们也可以通过它来实现。

也就是说,对于原生平台,我们现在有了两种选择:

libloading 的原理十分简单粗暴,就是利用链接器查找符号检查是否符合目标期望,如果期望则包装成为 Rust 的对象实例,方便调用。这也是标准的原生插件加载流程。

abi_stable 则使用分析修改 miri 等方式固化 ABI,并且实现了 Rust 标准库包装使得标准库 ABI 也进一步稳定,再继承 libloading 的流程使得实现安全的 Rust FFI 拓展。

请参照我实现的 eloader 项目来理解 abi_stable 的具体流程和用法,该库实现了一套很简单基础的拓展加载器。

wasm 平台

TODO

限制?

和 JVM 不同,实现原生平台的拓展系统无法直接访问宿主的诸如静态变量等字段,这是处于安全性考虑,也是加载机制导致的。

原生平台上,一个程序的内存地址实际上是虚拟内存地址,也就是说是“假”的内存地址。

并且,对于一个变量或者函数而言,一旦被 static 修饰,那么它就是模块私有的,这和 JVM 平台的逻辑完全不一样。

或者说,JVM 的 ClassLoader 就是一个巨大的模块,因此可以肆无忌惮的访问 static 成员——因为他们就在同一个模块里。

也就是说如果要访问这些变量或者函数,需要一个中间人作为其中的代理——例如上下文设计模式,传入已经重定位完成的 Context 结构体,其中包含各种对静态的调用,则可以间接实现这点,并且 Nginx 和 Apache 等实现了拓展系统的宿主均使用这种模式。

资源卸载

我们先认知一下资源到底是什么:

  • 文件句柄
  • 网络句柄
  • 事件资源

资源卸载是一种很难解决的问题——因为没有办法确定加载内容到底加载了什么资源,而且无法中断当前的状态实现卸载。

如果使用智能指针,例如引用计数等,实际上不能解决这个问题。资源卸载涉及到外部和系统的代数效应,程序内只能处理局部的代数效应。

理想环境

  • 拓展向宿主申请资源句柄,不自己使用任何资源句柄
  • 宿主重载拓展的时候会暂停当前任务,不再处理,然后等待拓展释放资源句柄
  • 资源句柄释放完毕,宿主卸载所有拓展
  • 卸载完毕,重新加载