动态插桩——不重编译,也能给算子"装监控"

举报
黄生 发表于 2026/09/18 09:23:08 2026/09/18
【摘要】 系列三 · 第 11 篇上篇埋了个钩子:工具在 rtKernelLaunch 这个口子、算子真正开跑前,做了一件事。这件事,就是本篇的主角——动态二进制插桩(DBI)。先回到一个矛盾。第 2 篇说过,要检测就得在编译时插桩,因为那些记录事件的"探针"是编译期埋进去的。可总有些场景没法重编译——算子二进制是别人给的,或者重编一次的代价太大。怎么办?答案是:不改源码、不重编译,直接对着已经编译好...

系列三 · 第 11 篇

上篇埋了个钩子:工具在 rtKernelLaunch 这个口子、算子真正开跑前,做了一件事。这件事,就是本篇的主角——动态二进制插桩(DBI)。

先回到一个矛盾。第 2 篇说过,要检测就得在编译时插桩,因为那些记录事件的"探针"是编译期埋进去的。可总有些场景没法重编译——算子二进制是别人给的,或者重编一次的代价太大。怎么办?答案是:不改源码、不重编译,直接对着已经编译好的算子二进制动手,在它即将运行的那一瞬间,现场给它安上探针。

这套"现场改装"分四步,全发生在 kernel 启动前的一小段时间里。

第一步,导出。工具把即将执行的算子二进制从设备的注册信息里 dump 出来,拿到一个二进制的"坯件"。

第二步,选桩。工具内部有一张巨大的对照表——就是探针绑定注册表里那数百条记录——写着"哪种昇腾指令,该配哪个探针函数"。它从表里挑出这个算子用到的指令所对应的探针,再从自己的插件库里把对应的探针实现段 dump 出来。

第三步,链接。把探针和算子坯件交给链接器,这里用的是 LLVM 家的 ld.lld——跟编译器同出一系。链接器把它们拼成一个可运行的整体,探针从此"长"在了算子的指令序列里。

第四步,调优。链接完还没完,得用昇腾的调优工具(bisheng-tune)再加工一遍,处理好跳转、生成最终二进制,重新注册回设备,这才真正执行。

于是,一份从没为检测编译过的算子,就在启动的瞬间被"改装"成了带监控的版本。代价是明显的:相比编译期静态插桩,它拿不到源码调试信息,报告里给不出"第几行代码"这种精确调用栈,只能说清"哪条指令、哪个核、碰了什么内存"。

说句公道话:这四步里,探针实现和那张对照表在本仓库(mssanitizer);而"导出二进制、调链接器、重新注册"的真正执行逻辑,放在另一个公共组件仓库(msopscommon)里。这也解释了为什么我们说它"玩操作"——它是整个工具里最贴近底层、也最依赖昇腾编译工具链的一环。

下一篇,我们顺着"探针"往下钻,看看一条昇腾指令,工具是怎么"读懂"它到底碰了哪块内存的。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。