运行时劫持——在不动你代码的前提下"接管"算子

举报
黄生 发表于 2026/09/18 09:11:00 2026/09/18
【摘要】 系列三 · 第 10 篇前面都在说工具"能查出什么",这篇换个视角,讲它"凭什么能插手"。你明明没把工具代码塞进算子里,它却能在算子运行时耳聪目明,越界、竞争一堆细节尽收眼底。秘密在于一个老牌的 Linux 机制:LD_PRELOAD。LD_PRELOAD 的作用,是允许你"顶替"动态库里的某些函数。具体到昇腾:算子在 host 侧干活时,要调用 runtime 提供的一堆接口——申请内存、...

系列三 · 第 10 篇

前面都在说工具"能查出什么",这篇换个视角,讲它"凭什么能插手"。你明明没把工具代码塞进算子里,它却能在算子运行时耳聪目明,越界、竞争一堆细节尽收眼底。秘密在于一个老牌的 Linux 机制:LD_PRELOAD。

LD_PRELOAD 的作用,是允许你"顶替"动态库里的某些函数。具体到昇腾:算子在 host 侧干活时,要调用 runtime 提供的一堆接口——申请内存、拉起 kernel、同步任务、拷贝数据。msSanitizer 提供了一个同名同型的钩子库,把其中几个关键接口"中途截住":先记录下这次调用要干嘛,再转手交给真正的 runtime 函数去执行。对算子来说一切如常、浑然不觉;对工具来说,每一次内存分配、每一次 kernel 启动,都在眼皮底下过了账。

这里有个精巧的小装置值得说说。截住了接口,总得知道"真身"在哪、怎么继续调它吧?工具用了一个叫 VallinaSymbol("原生态符号"之意)的东西,加载时把真正的 runtime 库打开、取出原函数指针存好。于是每个钩子的标准动作就成了:记一笔 → 调原函数 → 该干嘛干嘛。这也是"先上报、再放行"的由来。

被截住的关键接口分几层。最要紧的是 rtKernelLaunch 这一族——它们是启动算子的入口,工具正是在这一刻、算子真正开跑之前完成插桩的(下一篇细讲)。再往上,有 halMemAlloc、halMemFree 这类 HAL 层内存接口,以及 aclrtMalloc、aclrtFree 这类 ACL 层接口——截住它们,内存的分配释放、读写拷贝就有了记录。前面讲过的堆块台账、越界区间表,原始素材全从这里来。

剩下的工程问题是通信:工具主体和用户算子是两个进程,记录的事件怎么传回来?答案是 Unix Domain Socket——本机进程间聊天的标准通道。被劫持的算子进程当客户端,工具当服务端,一条 socket 把设备信息、kernel 信息、内存事件源源不断地递回去。多卡并发时,每张卡各连一条,服务端每个连接开一个线程,各收各的、互不打架。

下一篇,就顺着 rtKernelLaunch 这个口子,看看工具如何在算子开跑前"现场改二进制"——那是动态插桩,整套工具里最"玩操作"的一环。

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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