并发缺陷不再靠海量重跑:让智能体读懂语义,RaceBench 上多找出 38 个缺陷
导语
Reins 把大模型智能体对并发语义的推理变成调度约束,在 RaceBench 的 1500 个注入缺陷中触发 769 个,比最好的受控调度基线多 38 个,并在 Mozilla 的 NSPR 与 SpiderMonkey 中发现六个此前未知的并发缺陷。
正文
并发缺陷只在特定线程交错下出现,Reins 让智能体先读懂程序里哪些共享变量访问和同步操作在什么交错下会出错,再据此指挥线程调度去撞上这些交错。 此前的受控并发测试靠系统枚举或带概率保证的随机采样来探索交错空间,调度器在事件与执行这一层做决定,并不掌握程序语义,因此触发窗口窄、又依赖特定状态前提的缺陷在有限预算内很难暴露。 在 RaceBench 的 75 个目标、共 1500 个注入缺陷上,Reins 触发 769 个,是全部工具中最高的,比最好的基线 SURW 的 731 个多 38 个;在 SCTBench 与 ConVul 的 52 个单缺陷程序上,Reins 检出 48 个,SURW、RFF、PCT-3、PCT-10 与 RW 分别为 46、47、44、43 和 35 个。
智能体先从真实执行里观察到的共享变量访问出发,再按需读源码和查静态信息,把猜测写成一份只约束少数关键事件顺序和变量取值的调度计划。 调度器在每个调度点都要决定下一个跑哪个线程,一次运行可能有成千上万个这样的点,让智能体逐点决策不现实,而它的高层语义推理也无法直接翻译成具体的线程选择。 受控调度器只在计划涉及的那些调度点上按约束优先或推迟线程,其余调度点随机决定;计划里的事件和变量在执行前会先对着程序校验,触发缺陷的那次运行会记录调度轨迹以便确定性重放,未触发的运行则区分是交错没按计划发生,还是发生了却没有出现预期失败。
接下来
这套方法面向共享内存多线程程序,以给定的测试入口和输入为起点,只检测执行能到达的代码。它针对的是会表现为崩溃、断言失败或挂起的常见并发缺陷模式,包括数据竞争、原子性违反、顺序违反和死锁。评估覆盖三个公开基准和两个 Mozilla 项目 NSPR 与 SpiderMonkey,后者分别约 136 kLOC 和 1214 kLOC。
智能体输出的随机性是主要不确定来源,假设和计划可能在不同运行间不同,而每次运行成本高,因此每个工具和配置只跑了一次,且只用了一个模型。RaceBench 的注入缺陷会在源码里留下可识别的痕迹,作者机械地重命名相关标识符并去掉注入标记,但基准代码可能出现在模型训练语料中。所有工具在 5 小时预算内找到的注入缺陷都不超过约 51%,一部分原因是只用了种子输入,而有些注入缺陷需要其变异输入中的特定数据才能触发。
