第50期 | 偷听程序敲门的合法工具
一、偷听程序敲门的合法工具
一个程序在干什么,问它自己不如守在门口数
1991 年,Paul Kranenburg 在 SunOS 上写了 strace。起因很实在:Sun 自家的软件没源码,出了问题只能干瞪眼。他受 Sun 自带的 trace 工具启发,写了个"系统调用追踪器"¹。
1992 年 11 月,Branko Lankester 把它移植到 Linux,还顺手写了 Linux 内核侧的支持代码。1993 年,Rick Sladkey 把 SunOS 版和 Linux 版合并,3.0 在 1994 年中发布。此后维护权几经转手:1996 年 Wichert Akkerman,2002 年 Roland McGrath,2009 年起是 Dmitry Levin¹。三十多年,这个工具没换过赛道:守在系统调用的门口,记流水账。
它靠的是 ptrace——1979 年 Unix 第七版的手册里,就有 ptrace(2)²。玩法很直白:strace 先 fork 一个子进程,子进程喊一声 PTRACE_TRACEME("爹,你可以看我了"),然后每次进出系统调用都被内核拦停,父进程趁机读它的寄存器,把调用号、参数、返回值翻译成人话打印出来。
这套"拦路盘查"有个代价,手册 BUGS 节里明写着:"A traced process runs slowly"——被追踪的进程会变慢¹。观察,是要交税的。
strace 也不是只会看。2012 年加了路径追踪和文件描述符路径解码,2014 年能打栈回溯,2016 年更进一步:故障注入(-e inject=),能让被追踪进程的某个系统调用"假装失败"¹。从看,到动手,只差一个选项。
最妙的是它的边界。本机实测:拿 strace 去追踪另一个 strace,内层那个直接报 EPERM——被追踪的进程,自己不能再当追踪者。观察者无法被观察,自指在这里被内核锁死了。Hofstadter 在《GEB》里讲的怪圈³(思想化用):系统指涉自身时,会升起新的一级——在 strace 的世界里,那一级是上锁的。
照见一层平时看不见的。硬约束:系统调用是用户态和内核态之间唯一的门(第 41 期),想知道一个程序在干什么,除了读源码,就只剩守在门口数。谁在买单:被追踪的进程买单(变慢),运维和调试的人受益(没源码也能定位问题)。被大家默认的前提是错的:"程序在做什么"天生是个黑盒——不,黑盒是门太厚,不是里面没光。
二、AI 的世界没有"偷听":可观测性应该是出厂设置,不是外挂
如果操作系统的第一批用户是智能体,ptrace 这条路走不通。agent 的每一次"系统调用"——调工具、读写记忆、发消息——本来就是结构化的事件,不需要一个外部进程把它拦停、再翻译成人话。
推演:AI OS 里没有"追踪器"这个角色,因为追踪是架构属性。事件溯源那套思想:状态由事件流折叠出来。agent 的意图流,天然就是一条 strace 输出,只是它出生时就是人话,不需要解码。
DTrace 指过另一条路⁴。2004 年,Cantrill、Shapiro 和 Leventhal 在 USENIX 年会上发表《Dynamic Instrumentation of Production Systems》:不在进程外劫持,而在内核里布下几万个探针;探针没打开时,零开销——"zero probe effect"。这是偷听的进化:从拦路盘查,变成装路灯。灯一直装在那儿,开不开由你。
但也要诚实。ptrace 的粗暴恰恰是它的优点:不需要被追踪者配合,不需要改内核。AI OS 里如果有个 agent 拒绝上报自己的意图流,系统拿什么看它?可观测性若只靠自觉,等于没有。AI OS 仍需要一扇"不经同意也能看"的门——只是它该比 ptrace 更便宜、更安全。
范式之眼补一句:strace 按"调用"切分世界,一次系统调用是一个事件。可在向量阵列时代,算力的主体不是离散的调用,而是持续的张量流。AI OS 的 trace,也许不再是一行行调用记录,而是一段可回放的计算图执行轨迹。
三、今晚,给你的程序做一次心电图:三条 strace 命令
手边任何一台 Linux 机器,今晚就能试三条。
第一条,看程序怎么找文件、怎么死:
strace -e trace=openat,open,read,close ls /tmp/xyz-not-exist
输出里 openat(...) = -1 ENOENT 就是死因。线上"文件明明在却报找不到",十有八九是路径、权限、chroot 里某个环节撒了谎,strace 当场对质。
第二条,看一次列目录的代价:
strace -c ls /tmp
本机实测:71 次系统调用,一览表告诉你时间和次数花在哪。先养成习惯:觉得慢,先数数,再下结论。
第三条,贴上一个正在跑的进程:
strace -p <pid>
卡住的服务、转圈的任务,贴上去看它停在哪个调用上——是等网络(poll/recvfrom),还是等锁(futex)。这是线上救火的真家伙,不用重启,不用改代码。
落点。手边有跑本地模型的机器,推理慢了,先 strace 看看是不是卡在 IO(权重加载、日志刷盘)再怪 GPU;边缘盒上定位慢请求同理。视频 AI 平台、企业私有智能中心——给每个智能体的"工具调用"加一条 strace 式的审计轨迹:谁、什么时候、调了什么、花了多久、返回了什么。企业私有化场景里,这条轨迹就是"AI 到底做了什么"的唯一证据链。发展性研究之眼:strace 自己就是发展性研究的胜利——没发明新原理(ptrace 1979 年就有了),把现成的东西工程化成了神器。
觉 然 小 注
若以色见我,以音声求我,是人行邪道,不能见如来——化用《金刚经》第二十六分"法身非相分"的一偈⁵。程序的输出是色,日志是声;strace 不听它说什么,只数它敲了哪些门。
引 用 与 出 处
- [1] strace(1) 手册,HISTORY 与 BUGS 节(Debian manpages:原作者 Paul Kranenburg 为 SunOS 所写,Branko Lankester 1992 年 11 月移植至 Linux,Rick Sladkey 1993 年合并两版;维护沿革:Wichert Akkerman 1996 年、Roland McGrath 2002 年、Dmitry Levin 2009 年起;2012 年路径追踪、2014 年栈回溯、2016 年故障注入;BUGS 节 "A traced process runs slowly"). https://manpages.debian.org/buster/strace/strace.1.en.html
- [2] ptrace(2) 手册,Unix 第七版(1979)("ptrace - process trace"). https://www.unix.com/man-page/v7/2/ptrace
- [3] Hofstadter, D. R. Gödel, Escher, Bach: An Eternal Golden Braid. Basic Books, 1979(1980 年普利策奖). (怪圈与自指,思想化用)
- [4] Cantrill, B. M., Shapiro, M. W., & Leventhal, A. H. Dynamic Instrumentation of Production Systems. Proceedings of the USENIX Annual Technical Conference, pp. 15–28, 2004. https://static.usenix.org/events/usenix04/tech/general/cantrill.html
- [5] 鸠摩罗什 译. 《金刚般若波罗蜜经》第二十六分"法身非相分". 后秦弘始年间(约402年)译本. ("若以色见我,以音声求我"一偈,思想化用)
· · ·