当前位置: 首页 > news >正文

[论文阅读] 软件工程 | GPS算法:用“路径摘要”当向导,软件模型检测从此告别“瞎找bug”

GPS算法:用“路径摘要”当向导,软件模型检测从此告别“瞎找bug”

论文信息

项目详情
论文原标题Software Model Checking via Summary-Guided Search (Extended Version)
主要作者及机构1. Ruijie Fang(University of Texas at Austin, USA)
2. Zachary Kincaid(Princeton University, USA)
3. Thomas Reps(University of Wisconsin-Madison, USA)
APA引文格式Fang, R., Kincaid, Z., & Reps, T. (2025). Software Model Checking via Summary-Guided Search (Extended Version). ACM Transactions on Programming Languages and Systems, 1(1), 1-36. https://doi.org/10.1145/nnnnnnn.nnnnnnn
核心领域软件模型检测、静态分析、自动化测试
开源资源- Docker镜像:https://hub.docker.com/r/ruijiefang/gps-oopsla25-ae/
- 基准与代码:https://doi.org/10.5281/zenodo.16914158

一段话总结

本文提出一种名为GPS(Guided by Path Summaries) 的软件模型检测算法,将程序模型检测转化为“有向导的状态搜索”:通过静态分析生成的“路径摘要”(过近似输入输出关系的公式),既剪枝掉不可行路径、减少无效搜索,又引导测试生成以探索未覆盖状态;其创新的“两层搜索策略”(深度优先执行测试+广度优先生成测试)能高效处理“长输入依赖错误路径”(如需循环1000次的bug),还通过“gas变量 instrumentation”保证了“反驳完备性”(只要有bug,给足够时间就一定能找到)。在SV-COMP(ReachSafety-Loops类别)及“锁钥难题”(Lock & Key)等基准测试中,GPS在解决数量和运行时间上均超越现有顶尖模型检测工具。
在这里插入图片描述

研究背景:软件模型检测的“三难困境”与“痛点案例”

要理解GPS的价值,先得搞清楚它解决了什么“老大难”问题。软件模型检测的核心目标是证明程序安全(无bug)或找到bug(反例输入),但现有技术长期陷入“三难困境”:

1. 现有三大技术的“先天缺陷”

技术类型优点致命缺点类比场景
静态分析能证明程序安全不能找bug(过近似导致无法反驳)医院“全面体检”:能查慢性病,但漏诊急性病
自动化测试能找bug(生成测试用例)不能证明安全(覆盖不全)警察“巡逻抓小偷”:能抓现行,但不能保证无贼
传统模型检测既能证安全又能找bug慢、易超时、可能不终止(搜索空间爆炸)“地毯式搜索”:能找全,但费时间且可能迷路

2. 两大典型痛点案例(论文重点解决)

痛点1:“锁钥难题”(Lock & Key)——找不到“开门的钥匙”

比如论文中的EX-1程序(图1):要触发断言错误,需满足两个条件:① 循环执行至少1000次;② 输入N=1000(“钥匙”)。现有工具的问题:

  • 测试工具(如DART):随机生成N,很难碰巧选中1000,且循环1000次会超时;
  • 传统模型检测(如BMC):按路径长度递增搜索,没到1000次就耗尽资源。
痛点2:“长路径陷阱”——绕不出“无限循环”

比如论文中的状态机程序(图9):要触发错误,需依次输入“D→O→G”(状态机切换)+“C→A→T”(输入变量)。现有工具可能陷入“无限循环”:每次选c=0(非关键输入),永远到不了错误状态,导致Explore子程卡死。

3. 核心需求:需要一种“又准又快又全”的方法

  • 准:能精准定位“有效路径”,不做无效搜索;
  • 快:能跳过冗余路径,快速找到长依赖bug;
  • 全:只要有bug,就一定能找到(反驳完备),同时能证明安全。

创新点:GPS的“四大独门绝技”

GPS的突破在于把静态分析的“精准导航”、测试的“高效探索”、模型检测的“完备性”捏合成一个整体,核心创新有四个:

1. 摘要引导测试:不“瞎试”,只试“可能有bug的路径”

传统测试是“广撒网”,GPS是“精准钓鱼”——用静态分析生成的“路径摘要”(过近似输入输出公式)指导测试生成:

  • 摘要Sum(G,u,v):代表从节点uv的所有路径的“输入输出关系”(比如“min'=i'=kk≥1000”);
  • 测试生成逻辑:若w(π)∘Sum(G,dst(π),t)(路径π+从π终点到错误的摘要)可满足,则从模型中提取“可能触发bug的测试用例”,避免随机试错。

比如EX-1中,摘要直接给出“k≥1000”,GPS直接生成N=1000的测试,一次就命中bug。

2. 死端插值:生成“一劳永逸”的不变量

当测试生成失败(测试到不了错误),GPS不是直接放弃,而是提取“死端插值”:

  • 死端:路径π的所有延伸都到不了错误(比如EX-2中“r≥3”的路径,不可能满足“r=2”的错误条件);
  • 插值:从“w(π)∘Sum(...)不可满足”的证明中提取的状态公式(如“2|x”,表示x是偶数),能证明“所有延伸路径都不可行”。

比如EX-3中,死端插值“2|x”直接证明“x永远是偶数,不可能等于1”,一次性覆盖所有相关路径,不用逐个验证。

3. 两层搜索策略:兼顾“深度探索”与“广度覆盖”

GPS用“广度优先生成测试+深度优先执行测试”的组合策略:

  • 广度优先:从路径树的“前沿”(未探索路径)中选路径生成测试,避免陷入某一条无效路径;
  • 深度优先:执行测试时深入探索路径,快速覆盖长路径。

这种策略既不会像传统深度优先那样“一条路走到黑”,也不会像纯广度优先那样“浅尝辄止”,特别适合长输入依赖路径。

4. gas instrumentation:给“无限循环”装“刹车”

为了保证“反驳完备性”(只要有bug就一定能找到),GPS给程序加了个gas变量(类似“倒计时”):

  • 初始化:gas为非确定正整数;
  • 循环处:每次循环gas--,且gas≥0(否则退出循环);
  • 作用:强制Explore子程不会陷入“无限循环”,保证所有可能路径都会被公平探索。

比如状态机程序中,gas变量会迫使测试生成“让状态机前进”的输入(如c=68),否则gas耗尽就退出,避免卡死。

研究方法:GPS算法的“三步拆解”

GPS的逻辑链条非常清晰,可拆成“基础版(GPSLite)→完整版(GPS)→完备性保障(gas)”三步:

步骤1:GPSLite——核心逻辑的“简化版”

GPSLite是GPS的“骨架”,专注于“找bug+死端检测”,流程如下:

  1. 初始化:路径树T(存已探索路径)、前沿队列frontierQueue(存待探索路径),初始只有空路径;
  2. 循环探索
    • 从队列取路径π,用Check+原语判断“w(π)∘Sum(G,dst(π),t)是否可满足”;
    • 若可满足(SAT):调用Explore子程,从模型中提取测试用例,模拟执行并扩展路径树(若到错误则返回bug);
    • 若不可满足(UNSAT):标记π为死端,跳过(剪枝);
  3. 终止:队列空则证明安全,找到bug则返回反例。

步骤2:GPS——加入“不变量合成”的“完整版”

GPS在GPSLite基础上增加“证明安全”的能力,核心是抽象可达树(ART)

  1. ART结构:路径树T+标签L(路径的状态公式,如“2|x”)+覆盖边Cov(标记归纳不变量);
  2. 死端插值生成:当Check原语返回UNSAT时,提取插值序列(如⊤→2|x→2|x),用Refine子程强化路径标签,标记死端;
  3. 归纳不变量检查:用TryCover子程检查“子路径标签是否蕴含祖先标签”(如“x>1∧2|x蕴含2|x”),若满足则加覆盖边,证明循环不变量;
  4. 终止:ART无“前沿路径”(所有路径要么死端要么被覆盖)则证明安全。

步骤3:gas instrumentation——保障“反驳完备性”

为了避免Explore子程陷入无限循环,GPS对程序做“微小改造”:

  1. 新增全局变量gas,初始为非确定正整数;
  2. 在每个循环头部加代码:if (gas-- < 0) break;
  3. 效果:任何测试用例的执行步数都被gas限制,Explore必然终止,且GPS会“公平探索”所有可能路径(只要有bug,总有一个gas值能覆盖错误路径)。

关键优化:离线预计算摘要

GPS频繁需要“从任意节点到错误节点的摘要”,为了不重复计算,论文用Tarjan算法对偶化

  1. 反转程序控制流图(G→G^R);
  2. 定义“反向组合运算符”(F∘^R G = G∘F);
  3. 用Tarjan算法一次计算所有“单目标摘要”(从任意节点到错误节点),后续查询直接调用,效率提升线性倍。

主要成果:数据说话,GPS到底有多强?

论文用297个基准程序(SV-COMP+锁钥难题+安全例子)验证GPS,核心结果如下:

1. 三大研究问题(RQ)与结论

研究问题(RQ)实验设计核心结论
RQ1:GPS哪些组件最关键?消融实验:GPS vs GPSLite(无不变量)vs GPS-nogas(无gas)vs GPS-nogas-nosum(无摘要)1. 摘要(sum)是核心:无摘要时锁钥难题仅解决2/57;
2. gas提升稳定性:无gas时状态机例子仅解决3/6;
3. 不变量(GPS vs GPSLite):安全例子从4/9提升到9/9
RQ2:GPS vs 基础技术(CRA/Impact)对比CRA(静态分析)、Impact(模型检测)1. 比Impact多解决142个基准(136→278);
2. 比CRA多证明29个安全程序(156→185),且新增找bug能力
RQ3:GPS vs 顶尖工具?对比SV-COMP 2024顶尖工具(VeriAbs/Symbiotic/CPAChecker)1. 总解决数:GPS 278 > VeriAbs 236 > Symbiotic 183;
2. 锁钥难题:GPS 57/57全解决,VeriAbs仅28/57;
3. 运行时间:GPS平均9675s,比Symbiotic(87358s)快8倍

2. 核心贡献总结

贡献类型具体价值
理论贡献1. 提出“摘要引导搜索”框架,结合静态分析与测试;
2. 证明GPS的“反驳完备性”;
3. 死端插值:首次用摘要生成覆盖无限路径的不变量
工程贡献1. Tarjan算法对偶化:离线预计算摘要,提升效率;
2. gas instrumentation:低成本实现完备性
实践贡献1. 解决SV-COMP中多数“长路径+输入依赖”难题;
2. 开源工具与基准,供后续研究使用

关键问题

Q1:GPS如何解决“锁钥难题”中“找不到关键输入”的问题?

A:靠“摘要引导测试生成”。静态分析生成的路径摘要会直接给出“触发bug的输入约束”(如EX-1中“k≥1000”),GPS用SMT求解器从摘要中提取“关键输入”(N=1000),不用随机试错,一次就能命中。

Q2:“死端插值”和传统不变量有什么区别?

A:传统不变量(如Impact算法)是“逐路径生成”,只能覆盖单条路径;死端插值是“基于摘要生成”,能覆盖所有延伸路径(比如“2|x”能证明所有“x为偶数”的路径都到不了“x=1”的错误),质量更高,减少重复计算。

Q3:为什么“gas instrumentation”能保证“反驳完备性”?

A:因为它强制“所有测试用例都有长度上限”(由gas决定),Explore子程不会陷入无限循环。GPS按“广度优先”处理前沿路径,只要有bug,总有一个gas值能覆盖错误路径的长度,且GPS会公平探索所有可能路径,最终一定能找到bug。

Q4:GPS相比传统模型检测(如Impact),为什么更快?

A:有两个关键原因:① 摘要剪枝:提前排除不可行路径,减少搜索空间;② 离线摘要:用Tarjan算法对偶化预计算所有“单目标摘要”,后续查询不用重复分析循环,节省时间;③ 两层搜索:深度优先执行测试+广度优先生成测试,平衡“深度”与“广度”,避免无效探索。

总结:GPS的“得与失”与未来方向

1. 核心优势

  • 高效:摘要引导+剪枝,解决长路径、输入依赖bug的效率远超现有工具;
  • 全能:既能证明程序安全(死端插值+ART),又能找bug(测试生成);
  • 可靠:gas instrumentation保证“反驳完备性”,只要有bug就一定能找到;
  • 易用:开源工具+基准,可直接复用,支持线性整数算术(LIA)程序。

2. 现有局限

  • 适用范围:目前仅支持“过程内程序”(无函数调用)和“线性整数算术”(无指针、数组);
  • 摘要精度:摘要的过近似可能导致“假阳性测试”(生成的测试到不了错误),需额外处理;
  • 性能开销:不变量合成(死端插值+TryCover)会增加少量计算成本。

3. 未来方向

  • 扩展到“跨过程程序”:结合Spacer等跨过程模型检测框架;
  • 支持更复杂数据类型:如数组、指针、堆内存;
  • 提升摘要精度:用更精准的代数程序分析技术(如非线性不变量)减少假阳性。
http://www.xdnf.cn/news/1358083.html

相关文章:

  • Kaggle项目:一次 Uber 出行数据分析的完整思路
  • 【机器学习】 11 Mixture models and the EM algorithm
  • 如何捕获组件的异常情况
  • Node.js依赖管理与install及run命令详解
  • Redis实战-缓存的解决方案(一)
  • Flink直接缓冲存储器异常解析与解决方案
  • comfyUI背后的一些技术——CLIP
  • 暗影哨兵:安全运维的隐秘防线
  • 高并发AI服务部署方案:vLLM、TGI、FastChat性能压测报告
  • 使用 Fargate 在 AWS ECS 上运行 Spring Boot 应用程序
  • QML Charts组件之坐标轴示例
  • maven私服架构
  • Tesla智能座舱域控制器(MCU)的系统化梳理
  • ChainVault:重塑亚洲黄金交易基建,引领RWA金融新浪潮
  • Vue 3多语言应用开发实战:vue-i18n深度解析与最佳实践
  • 项目学习总结(4)
  • 【(含模板)滑动窗口 - LeetCode】3. 无重复字符的最长子串
  • 基于深度学习的餐盘清洁状态分类
  • 基于stm32汽车雨刮器控制系统设计
  • 普元低代码开发平台:开启企业高效创新新征程
  • SQL Server从入门到项目实践(超值版)读书笔记 24
  • 【C++】 9. vector
  • 线段树相关算法题(2)
  • 3D打印机管理后台与RabbitMQ集成的业务场景
  • Windows Server存储副本智能同步优化方案
  • 【RAGFlow代码详解-4】数据存储层
  • 第四章:大模型(LLM)】07.Prompt工程-(12)其他prompt方法
  • 人工智能之数学基础:离散型随机变量
  • 【中文教材】13. 资本流动与外汇市场
  • Redis 高可用开发指南