用于确定多项式增长界限的静态分析器
1 pymwp简介
pymwp是一款用于分析C程序变量多项式增长界限的静态分析器,其分析过程自动且只读,可与其他工具结合,集成到编译或验证工具链中。在线演示就是一个将pymwp作为包依赖的Web服务器应用示例,其他衍生用途也可类似开发。
1.1 安装与使用
安装pymwp最简单的方法是通过PyPI,使用命令
pip install pymwp
。默认的交互命令为:
pymwp path/to/file.c [args]
其中,第一个位置参数是必需的。默认情况下,pymwp会显示带有日志信息的分析结果,并将结果写入文件,此行为可通过指定参数进行自定义。若要查看当前支持的参数列表,可运行
pymwp --help
。
1.2 可分析程序的范围
pymwp可分析的程序由其支持的语法决定。它将解析C文件的任务委托给依赖项pycparser,该工具旨在支持完整的C99规范。无法解析的程序会抛出错误,否则分析将在生成的抽象语法树(AST)上进行。pymwp会处理其演算语法支持的节点,跳过不支持的节点并给出警告。为了获得部分结果并手动检查不支持的操作,采用了这种宽松的处理方式。不过,要确定一个有保证的界限,输入程序必须完全符合演算支持的语法。目前,其语法存在一定限制,例如不支持数组和指针操作,扩展分析以支持更丰富的语法是未来的工作方向。
2 技术改进
2.1 细化分析结果的动机
最初设计的mwp - flow推理系统计算成本过高,它会非确定性地处理指数数量的大型矩阵来尝试确定界限。改进后的mwp技术将非确定性内化到单个矩阵中,把所有推导(包括会失败的推导)同时构建出来,将问题从“是否存在推导?”转变为“在所有构建的推导中,是否有一个不包含∞系数的推导?”。虽然回答第一个问题计算成本过高,但pymwp的FSCD 2022版本可以回答第二个问题,并且如果所有推导都包含∞系数,还能提前终止以更快得到结果。这得益于复杂的Relation数据结构,但从该数据结构中提取更精细的信息仍是一个待解决的问题。当前版本的pymwp现在可以为程序员提供以下反馈:
- 如果不存在界限,指出指数增长的位置。
- 如果存在界限,给出至少一个界限的值。
2.2 暴露失败源
由于pymwp用于识别多项式界限,对于包含至少一个变量相对于其初始值呈指数增长的程序,它会报告失败。早期版本的工具只会指出检测到失败,而不报告涉及的变量。确定这些信息虽然因非确定性处理而复杂,但很有价值,因为解决其中一个失败点就可能获得多项式增长界限。即使程序无法令人满意地重构,分析指数增长也有助于评估对父软件应用程序的潜在影响。
解决方案是在Relation数据结构中记录关于∞系数的额外信息,并列出所有可能发生失败的变量对。由于详细的失败信息在某些用例中可能无关紧要且计算成本高,因此将其作为可选的
--fin
参数添加。
示例代码如下:
int foo(int X1 , int X2 , int X3){
if (X1 == 1){
X1 = X2+X1;
X2 = X3+X2;
}
while(X1 < 10){
X1 = X2+X1;
}
}
运行命令:
$ pymwp infinite/infinite_3.c --fin
输出结果:
foo is infinite
Possibly problematic flows:
X1 →X1 ∥X2 →X1 ∥X3 →X1
解读为“X1过于强烈地依赖于所有变量”。
2.3 高效确定界限
当确定存在界限时,下一步是评估这些界限。然而,演算可能会产生与程序大小呈指数关系的界限数量,导致评估阶段(如从推导集合中提取界限)的成本越来越高。为了高效处理这个任务,需要找到一种计算解决方案,并以可解释且内存高效的方式表示结果。
确定mwp界限需要两个步骤,从分析阶段生成的Relation数据结构开始。首先要确定推导集合中哪些路径产生界限(即不包含∞)。简单的暴力解决方案是遍历所有路径,但这在实际应用中太慢。因此,采用了集合论方法,先确定所有导致∞的推导路径,然后取反这些路径。将这个过程封装在一个名为Choice的结构中,计算结果称为选择向量。选择向量以紧凑的、类似正则表达式的表示形式包含所有产生界限的推导路径。一旦知道这些路径,就可以通过应用选定的路径从Relation中提取mwp界限(表示为Bound对象)。目前,从选择向量中取第一个选择并将其作为结果显示。
以下是确定mwp界限的流程:
graph TD;
A[开始] --> B[分析阶段生成Relation数据结构];
B --> C[确定导致∞的推导路径];
C --> D[取反路径得到选择向量];
D --> E[从选择向量中选择路径];
E --> F[从Relation中提取mwp界限];
F --> G[显示结果];
G --> H[结束];
3 实验评估
3.1 方法论
为了验证pymwp是一个实用且高效的静态分析器,在一组标准C程序的基准测试套件上进行了评估。运行分析器并测量结果,以评估其性能和行为的正确性。未进行工具比较或使用标准套件,原因一是缺乏有代表性的比较目标,二是语法限制限制了可分析程序的范围。但选择的方法能合理评估pymwp,并便于实验的透明性和可重复性。
3.1.1 基准测试描述
该套件包含50个C程序,采用pymwp支持的C99语法子集编写。这些基准测试旨在测试各种对分析器构成挑战的数据流,如递增参数、二元运算、循环和决策等。基准测试根据预期结果(∞与非∞)、相关出版物来源以及趣味性等因素分为七个类别。套件可从pymwp仓库获取,也可在GitHub和Zenodo上找到。
3.1.2 指标
对于每个基准测试,记录以下指标:
1.
基准测试名称
:对应C文件名称,若文件包含多个程序,还会列出程序名称。
2.
代码行数(loc)
:范围在4到45之间,由于分析是组合式的,即使是大型C文件的分析也可简化为对类似大小函数的分析。
3.
完成程序分析所需时间(ms)
:使用毫秒为单位以保证精度,所有分析都在数秒内完成。对于∞程序,该时间是进行带反馈的完整评估所需的时间,实际上存在失败结果可更快获得。
4.
程序初始值数量(vars)
:会影响分析的复杂度。
5.
分析器发现的多项式界限数量
:若结果为∞,则界限数量为0。
6.
若程序可推导,捕获其中一个界限
。
3.1.3 实验设置
测量在Linux x86_64系统上进行,内核版本为v.5.4.0 - 1096 - gcp,Ubuntu 18.04,8核32GB虚拟内存。机器仅影响观察到的执行时间,其他指标是确定性的。软件环境为Python运行时3.8.0、gcc 7.5.0、GNU Make 4.1以及pymwp的开发依赖项。由于pymwp的测量工具未随发布版本分发,实验必须从源代码运行,使用的源代码版本为0.4.2。重复实验的命令为
make bench
,该命令会对基准测试进行分析并生成两个结果表。
3.2 结果
评估结果如表2所示,重点关注获得的界限及其正确性,执行时间提供性能参考信息。分析器能正确为非无限的基准测试找到多项式界限,拒绝指数和无限的基准测试,还能为可能不终止的while基准测试推导界限。即使对于代码行数为45的长示例和初始值数量为18的explosion示例,分析也能快速完成。长示例的界限数量高是因为其推导复杂且内部非确定性程度高。
表2:C程序标准测试套件的基准测试结果
| # | 基准测试 | loc | ms | vars | bounds |
| — | — | — | — | — | — |
| 1 | assign_expression | 8 | 0 | 2 | 3 |
| 2 | assign_variable | 9 | 0 | 2 | 3 |
| 3 | dense | 16 | 15 | 3 | 81 |
| 4 | dense_loop | 17 | 66 | 3 | 81 |
| 5 | example14: f | 4 | 2 | 2 | 1 |
| 6 | example14: foo | 11 | 0 | 2 | 3 |
| 7 | example16 | 15 | 7 | 4 | 27 |
| 8 | example3_1_a | 10 | 1 | 3 | 9 |
| 9 | example3_1_b | 10 | 2 | 3 | 9 |
| 10 | example3_1_c | 11 | 3 | 3 | 1 |
| 11 | example3_1_d | 12 | 1 | 2 | 0 |
| 12 | example3_2 | 12 | 2 | 3 | 0 |
| 13 | example3_4 | 22 | 14 | 5 | 0 |
| 14 | example5_1 | 10 | 0 | 2 | 1 |
| 15 | example7_10 | 10 | 1 | 3 | 9 |
| 16 | example7_11 | 11 | 9 | 4 | 27 |
| 17 | example8 | 8 | 1 | 3 | 9 |
| 18 | explosion | 23 | 405 | 18 | 729 |
| 19 | exponent_1 | 16 | 7 | 4 | 0 |
| 20 | exponent_2 | 13 | 4 | 4 | 0 |
| 21 | gcd | 12 | 10 | 2 | 0 |
| 22 | if | 7 | 0 | 2 | 3 |
| 23 | if_else | 7 | 0 | 2 | 9 |
| 24 | infinite_2 | 6 | 16 | 2 | 0 |
| 25 | infinite_3 | 9 | 7 | 3 | 0 |
| 26 | infinite_4 | 9 | 2189 | 5 | 0 |
| 27 | infinite_5 | 11 | 518 | 5 | 0 |
| 28 | infinite_6 | 14 | 1031 | 4 | 0 |
| 29 | infinite_7 | 15 | 298 | 5 | 0 |
| 30 | infinite_8 | 23 | 722 | 6 | 0 |
| 31 | inline_variable | 9 | 0 | 2 | 3 |
| 32 | long | 45 | 2875 | 5 | 177147 |
| 33 | notinfinite_2 | 4 | 1 | 2 | 9 |
| 34 | notinfinite_3 | 9 | 7 | 4 | 9 |
| 35 | notinfinite_4 | 11 | 30 | 5 | 3 |
| 36 | notinfinite_5 | 11 | 29 | 4 | 9 |
| 37 | notinfinite_6 | 16 | 34 | 4 | 81 |
| 38 | notinfinite_7 | 15 | 283 | 5 | 9 |
| 39 | notinfinite_8 | 22 | 856 | 6 | 27 |
| 40 | simplified_dense | 9 | 1 | 2 | 9 |
| 41 | t19_c4b | 9 | 2 | 2 | 81 |
| 42 | t20_c4b | 7 | 1 | 2 | 9 |
| 43 | t47_c4b | 12 | 1 | 2 | 3 |
| 44 | tool_ex_1 | 7 | 5 | 3 | 1 |
| 45 | tool_ex_2 | 7 | 0 | 2 | 0 |
| 46 | tool_ex_3 | 9 | 8 | 3 | 3 |
| 47 | while_1 | 7 | 1 | 2 | 3 |
| 48 | while_2 | 7 | 1 | 2 | 1 |
| 49 | while_if | 9 | 3 | 3 | 9 |
| 50 | xnu | 26 | 17 | 5 | 6561 |
对于具有多项式增长界限的程序,给出简化的示例界限,如下表所示:
| # | 基准测试 | 界限 |
| — | — | — |
| 1 | y2′ ≤y1 | |
| 2 | x′ ≤y | |
| 3 | X0′ ≤max(X0, X2) + X1 ∧X1′ ≤X0 × X1 × X2 ∧X2′ ≤max(X0, X2) + X1 | |
| 4 | X0′ ≤max(X0, X2) + X1 ∧X1′ ≤X0 × X1 × X2 ∧X2′ ≤max(X0, X2) + X1 | |
| 5 | X2′ ≤max(X2, X1) | |
| 6 | X2′ ≤X1 | |
| 7 | X1′ ≤R + X1 ∧X2′ ≤X1 ∧X_1′ ≤X1 ∧R′ ≤R + X1 | |
| 8 | X1′ ≤X2 + X3 | |
| 9 | X1′ ≤X2 × X3 | |
| 10 | X1′ ≤max(X1, X2 + X3) | |
| 15 | X3′ ≤X3 + X1 × X2 | |
| 16 | X1′ ≤X1 + X2 × X3 × X4 ∧X2′ ≤X2 + X3 × X4 ∧X3′ ≤X3 + X4 | |
| 17 | X1′ ≤X1 + X2 × X3 | |
| 18 | x0′ ≤x1 + x2 ∧x3′ ≤x4 + x5 ∧x6′ ≤x7 + x8 ∧x9′ ≤x10 + x11 ∧x12′ ≤x13 + x14 ∧x15′ ≤x16 + x17 | |
| 22 | y′ ≤max(x, y) | |
| 23 | x′ ≤max(x, y) ∧y′ ≤max(x, y) | |
| 31 | y2′ ≤y1 | |
| 32 | X0′ ≤X2 + X1 × X4 ∧X1′ ≤max(X2, X3, X4) + X1 ∧X2′ ≤max(X2, X3) + X1 × X4 ∧X3′ ≤max(X2, X3) + X1 ∧X4′ ≤X1 × X2 × X3 × X4 | |
| 33 | X0′ ≤X0 + X1 ∧X1′ ≤X0 × X1 | |
| 34 | X0′ ≤max(X0, X1) + X2 × X3 ∧X1′ ≤X1 + X2 ∧X2′ ≤X2 + X3 | |
| 35 | X1′ ≤max(X1, X2 + X3) ∧X2′ ≤max(X2, X3) ∧X4′ ≤max(X4, X5) | |
| 36 | X1′ ≤max(X1, X4) + X2 × X3 ∧X2′ ≤max(X2, X4) + X3 ∧X3′ ≤max(X3, X4) | |
| 37 | X1′ ≤max(X1, X4) + X2 × X3 ∧X2′ ≤max(X2, X4) + X3 | |
| 38 | X1′ ≤max(X1, X2 + X3 + X4 + X5) ∧X2′ ≤max(X2, X3 + X4 + X5) ∧X3′ ≤max(X3, X4 + X5) ∧X4′ ≤max(X4, X5) | |
| 39 | X1′ ≤X1 + X2 × X3 × X4 × X5 ∧X2′ ≤max(X2, X1 + X3 + X4 + X5) ∧X3′ ≤max(X3, X1 + X4 + X5) + X2 ∧X4′ ≤max(X4, X1 + X5) + X2 ∧X6′ ≤max(X6, X1 + X3 + X4 + X5) + X2 | |
| 40 | X0′ ≤X0 + X1 ∧X1′ ≤X1 + X0 | |
| 41 | i′ ≤i + k | |
| 43 | flag′ ≤0 | |
| 44 | X2′ ≤max(X2, X1) ∧X3′ ≤max(X3, X1 + X2) | |
| 46 | X2′ ≤max(X2, X1) ∧X3′ ≤X1 + X2 + X3 | |
| 47 | y′ ≤max(x, y) | |
| 48 | x′ ≤max(x, y) | |
| 49 | y2′ ≤max(y2, y1) ∧r′ ≤max(y2, y1) | |
| 50 | beg′ ≤0 ∧end′ ≤0 ∧i′ ≤0 | |
这些表格展示了pymwp能够自动推导复杂的多变量界限,并以易于理解的形式呈现非确定性计算的结果,同时明确了分析器的计算内容和结果的独特性。
4 总结与展望
4.1 总结
pymwp是一款高效的静态分析器,能够有效推理变量相对于其初始值的增长界限是否存在。它可以与其他工具结合,用于扩展验证和复合分析。通过在标准C程序基准测试套件上的评估,证明了pymwp在性能和行为正确性方面表现良好,能够正确识别非无限程序的多项式界限,并拒绝指数和无限程序。
以下是pymwp的主要特点总结:
-
易于集成
:分析过程自动且只读,可与其他工具集成到编译或验证工具链中。
-
语法支持
:委托pycparser解析C文件,支持C99规范的子集,但目前存在一定语法限制。
-
技术改进
:通过改进的mwp技术和复杂的Relation数据结构,提高了分析效率,并能提供更精细的反馈。
-
实验验证
:在基准测试中表现良好,能够快速分析复杂程序,并推导出复杂的多变量界限。
4.2 未来可能的增强方向
虽然pymwp已经取得了显著的进展,但仍有一些方面可以进一步改进和扩展:
-
支持更丰富的语法
:目前pymwp的语法存在一定限制,如不支持数组和指针操作。未来可以扩展分析以支持更丰富的语法,从而扩大可分析程序的范围。
-
探索发现的界限空间
:可以进一步研究发现的界限,例如调查是否存在满足特定约束(如某个变量线性增长)的界限,以及识别不同的界限。
-
形式验证分析技术
:对分析技术进行形式验证,确保其正确性和可靠性。
-
扩展应用场景
:由于分析不需要输入程序具有太多结构,因此可以用于编译过程中的中间表示分析,也可应用于特定领域语言和资源受限的硬件,以保证其运行时行为。
-
开发IDE插件
:利用快速的组合分析能力,开发IDE插件,为程序员提供低延迟的反馈。
4.3 未来工作的探索流程
graph LR;
A[扩展语法支持] --> B[研究界限空间];
B --> C[形式验证技术];
C --> D[扩展应用场景];
D --> E[开发IDE插件];
综上所述,pymwp是一款有潜力的静态分析工具,通过不断的改进和扩展,有望在软件验证和分析领域发挥更大的作用。未来的研究和开发工作将围绕上述方向展开,以进一步提升pymwp的性能和功能。
超级会员免费看
10

被折叠的 条评论
为什么被折叠?



