1.简介
别名分析是编译器理论中的一种技术,用于确定存储位置是否可以以多种方式访问。如果两个指针指向相同的位置,则称这两个指针为别名。但是,它不能与指针分析混淆,指针分析解决的问题是一个指针可能指向哪些对象或者指向哪些地址,而别名分析解决的是两个指针指向的是否是同一个对象。指针分析和别名分析通常通过静态代码分析来实现。
别名分析在编译器理论中非常重要,在代码优化和安全方面有着非常广泛且重要的应用。编译器级优化需要指针别名信息来执行死代码消除(删除不影响程序结果的代码)、冗余加载/存储指令消除、指令调度(重排列指令)等。编译器级别的程序安全使用别名分析来检测内存泄漏和内存相关的安全漏洞。
2.别名分析分类
别名分析种类繁多,通常按如下属性进行分类:域敏感度(field-sensitivity)、过程内分析(Intra-Procedural)v.s.过程间分析(Inter-Procedural)、上下文敏感度(context-sensitivity)和流敏感度(flow-sensitivity)。
2.1 域敏感(Field-Sensitivity)
域敏感度是对用户自定义类型进行分析的一种策略(亦可以处理数组)。在域敏感维度共有三种分析策略:域敏感(field-sensitive)、域非敏感(field-insensitive)、域基础分析(field-based)。以下面代码为例:
struct Test {
int field1;
int field2;
}
Test a1;
Test a2;
Note:field这里为结构体或者类的数据成员。
域非敏感:对每个对象建模,而对对象中的成员不进行处理;其建模后的结果如下图,仅有a1.*和a2.*的区别:

域基础分析:仅对结构体中的成员进行建模,而不感知对象。其建模后的结果如下图,仅有*.field1和*.field2:

域敏感:既对对象建模,又对成员变量进行处理。其建模后的结果如下图,有a1.field1、a1.field2、a2.field1、a2.field2:

处理数组时,相同的原则亦适用。以C整数数组为例:int a[10],域非敏感分析仅使用一个节点建模:a[*],而域敏感分析创建10个节点:a[0]、a[1]、…、a[9]。
总结:域敏感别名分析准确性高,但是当存在嵌套结构或者大数组时,节点数量会迅速增加,分析成本也会陡然上升。
2.2 过程内分析(Intra-Procedural)v.s.过程间分析(Inter-Procedural)
过程内分析仅分析函数体内部的指针,并没有考虑与其他函数之间的相互影响。需要特别指出的是,过程内分析当处理包含指针入参的函数或者返回指针的函数时,其分析可能不够准确。相反,过程间分析会在函数调用过程中处理指针的行为。
过程内分析不易于扩展,精度较低。相比过程间分析,过程内分析更容易实现,且过程内/间分析与上下文敏感度分析高度相关,因为一个上下文敏感分析必定是一个过程间分析。

最低0.47元/天 解锁文章

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



