哈哈小说
第 6 卷 · AI 的前夜 · 第 109 章 · 97 段 · 3116 字

TODO

第一百〇九章 TODO

那行注释在手机屏幕上看起来很短。

`// TODO: verify isolation context before fault propagation`

图片存了,给麦景行回:「能查到这个提交是谁做的吗?」

「正在看,git log 有记录,等我一下。」


他去倒了杯水,回来手机上多了一条消息。

「查到了。不是邓工。」

「是谁?」

麦景行停了几秒,发过来:「用户名 `wl_g1dev`,邮箱是泉华内网的,名字显示魏磊,G1 开发组。」

把这个名字记下来。G1 开发组的人,跑进了 `common/` 里。

「提交时间?」

「5月12号,下午两点四十七分。」

5 月 12 日。合同是 5 月初签的,初次扫描是第二周。5 月 12 日,他们这边刚刚开始第一轮代码摸底。

时间线对上了。


「魏磊现在在哪个组?」他问。

「不清楚,要查的话得走泉华内部。」

「加上去之前,原来的代码是什么样的?」

「空的,」麦景行回,「函数体里只有几行基础的状态写入,其他什么都没有。魏磊加了这一行,推上去,没有其他修改。」

空函数体,加一行 TODO,推了。

这不像在修代码,更像是在给将来某个会来查的人留一个信号,然后走掉了。


他给豆包发了消息,附上截图。

插图

豆包回来很快,发了一段解释。

`verify isolation context before fault propagation`,字面意思:在传播故障信号之前,先确认隔离上下文是否就绪。工控安全里对应的场景是:如果 `set_system_fault` 被调用时,调用方和周围模块之间的隔离没有完成,比如共享状态没清空、内存锁没释放,故障信号传播出去,接收方拿到的就是中间态。

「后果是什么?」

「取决于接收方的处理方式。最坏的情况是接收方基于这个中间态继续运行了一段时间,然后在错误的时间点停止。工控里,停机指令出了顺序,有时比不停更危险。」

把那段话看了两遍。

他们一直在查 ERR_HANDLER 什么情况下会触发。豆包解释的这个,是触发之后可能出什么岔子。两件事,都没有写在任何文档里。


这行注释现在不只是一个未完成事项了。

有人在内部意识到了这个风险,写下来,然后就停在那里了,没有任何后续。

把豆包的分析截图发给乔木,什么都没说。

回复来了,用了大概两分钟。

「这改变了一件事。」

「说。」

「之前我们来这里,是帮泉华把已知的东西写清楚。现在这个情况,至少有一个人在内部已经知道这里有问题,但这件事没有走到任何地方。」

「意思是?」

「内部风险已知,没有对外披露。比注释缺失严重一个等级,法律属性不一样。」

没有立刻回。


「你觉得方总知道吗?」乔木发过来。

这个问题在脑子里转了一会儿。

方晓晨在 5 月初把他们引进来,说是 G1 代码注释有合规缺口。监管检查在十一月。引进审计组之后第二周,G1 开发组有人去碰了 `set_system_fault`,加了一行 TODO 然后消失了。

插图

如果方晓晨知道,引进他们就是为了让外部审计把这个风险记录在案,把责任分出去一部分。如果她不知道,这件事就是内部有人意识到了,但从来没有向上汇报过的坑。

两种情况,处理方式完全不同。

「现在还不知道,」他给乔木回,「先不找她。」

「好,先查清楚这个 TODO 背后的实际意义,再决定怎么谈。」


给麦景行发了新任务:查一下 `set_system_fault` 在整个代码库里还有没有别的调用方,除了 G1 旁路那一处。

「有,我进来之后扫过,两处。」

「旁路是 G1 的那处,另外一处?」

「在 G2 模块里,文件是 `g2/recovery_handler.c`,函数名 `handle_recovery_fail`。」

「G2 那边也在调?」

「路径不同。G2 那边是通过条件宏展开的,`ERR_HANDLER` 这个宏在 G2 里也有,展开出来的函数名一样,也是 `set_system_fault`。」

「`ERR_HANDLER` 在 G2 里的定义在哪个文件?」

他突然想到什么,在麦景行回之前又发了一条:「让我猜一下——如果这个宏定义在 `common/` 里,就不是 G1 的问题,也不是 G2 的问题。」

麦景行停了一下。

「等一下。」

「怎么了?」

「头文件是 `common/err_handle.h`,G1 和 G2 的宏定义在同一个里面。」

「对的。」

这个情况在脑子里过了一遍。


两套独立的合同模块,通过同一个 `common/` 里的宏,调用同一个函数。设计上两边隔离,但入口是一个。

魏磊改的是 `common/err_handle.h`,是 BasePlatform 的地盘,不是 G1 的范围。写这行注释的人清楚:这个函数有不止一个调用方,各自的隔离状态不一样。然后停在这里,没有继续。

插图

「这行 TODO 在头文件里的什么位置?」

「紧跟在 `set_system_fault` 函数声明前面,一行。」

一个 G1 工程师,进了 BasePlatform 的地盘,加了一行 TODO,推上去,然后没有人回应过这个提交。

邓明海做了十八年 BasePlatform,这件事没有被提过。或者发现了,也没有说。


「去查一下这个提交有没有经过 code review。」他给麦景行说。

等了大概三分钟。

「没有,」麦景行的回复很短,「直接推到了主干,没有任何 review 记录,也没有关联工单。」

手机放下来。

在合同签完后的第二周,G1 开发组有人直接推了一个没经过 review 的提交进 `common/`,加了一行 TODO,然后这件事就消失在版本历史里,直到今天才被看见。

这不是巧合。

但背后是什么,现在还不够清楚。

「魏磊在 5 月 12 号之后还有别的提交吗?」他问。

「只有这一次。」麦景行回,「`common/` 里只有这条记录。G1 模块下面他有正常提交,从 2023 年开始,最后一次是 4 月底。」

4 月底是他在 G1 的最后记录,5 月 12 日越界进了 `common/`,然后再没出现过。

「他现在还在泉华吗?」

「没办法查到人事信息。」


消息又来了,应该是乔木也在消化这些信息。

「我理解一下现在的情况:G1 工程师发现了一个跨模块问题,没走内部报告,没申请 review,直接在 BasePlatform 的文件里加了一行 TODO,然后就停了。」

「对。」

插图

「问题是,」乔木停顿了一下,「合同里扩展的三项工作,现在实际上是四项。第四项是确认 G1 和 G2 共享调用路径的隔离状态是否满足安全要求。但这一项不在合同里。」

把这句话看了两遍。

合同里没有这项,但现在不写进报告,报告就是残的。写进去,就要再谈。

「先让麦景行把 G2 那边的调用链拉出来,两条路径一起看清楚,再决定怎么跟方总说。」


他放下手机,椅背上靠了一会儿。

窗外是楼道的灯,快八点了。麦景行应该还在电脑前面。

他想起邓明海那个背景里的旧书和挂件,想起那句「能跑就行」。三十年前设计这套系统的人,仔细的重点在别的地方:机器能跑,故障能止住,链路通。文档、注释、跨模块依赖,当时不是重点。

后来重点变了。

这行 TODO 是那个变化的某个截面。有人开始意识到,能跑和安全,不完全是同一件事。他写下来,然后停在那里,等别人来看。

现在有人来了。

手机亮起来。麦景行发来一张截图,`g2/recovery_handler.c`,有高亮标注。

「陆哥,G2 那条路,`set_system_fault` 是在 recovery 失败的最终路径里调的,调用时 G2 的内存锁已经释放了。」

「也就是说——」

「G1 和 G2 同时触发,进的是同一个函数,但一个有锁,一个没锁。」

用人话说就是:两列火车,同一个道叉,一列踩着刹车进的,一列刹车已经松了。进同一道叉,出来什么没人知道。

屏幕在桌上亮着,那行字停在那里。

他给麦景行发了一条:「魏磊,这个人还在泉华吗?想办法查一下。」

放下手机,靠在椅背上。

见方晓晨之前,得先搞清楚魏磊在哪里,以及他当时看到了什么。