Motivation
明显,类层次分析没法很好完成invokeinterface的分析。
Intro
作用:
- 确定某个指针能够指向何处memory
- 对oop能够确定指针指向的具体是哪个class的方法,field等
一般是may analysis
Pointer Analysis & Alias Analysis
注意区分这二者实际上是不同的任务,尽管pointer analysis有能力得到alias analysis所需的信息。
潜在应用场景
- 用于建立call graph
- 用于优化编译器,比如virtual call inlining
- 用于bug detection,例如null pointer detection
- 用于安全分析
- ...
key factors
Pointer Analysis可以在多个问题上做出取舍,比如如何对堆建模,如何对上下文建模,如何对控制流建模,是否需要分析整个程序还是仅仅分析感兴趣的。
heap memory
在实际执行中,heap objects可能会因为loops和recursion无限制增长。
A[] As;
loop{
As.append(new A());
}
为此,heap abstraction models将这些动态分配的,可能无限大的objects直接视为一个finite abstract objects,也即忽视构成元素个数。
课件主要强调常用的allocation-site abstraction
Allocation-Site Abstraction
将创建的程序点抽象为object来分析。例如下图(O_2),代表在第2行创建的object。
Context Sensitivity
如果区别调用的上下文,能增进精度,同个方法可能需要分析多次。
FLow Sensitivity
这里flow insensitive算法在全局维护单个point-to relations map。实践上,往往flow sensitive的提升并不大。
Analysis Scope
Concerned
- 只关心pointer-affecting statements
- New
- Assign
- Store: 如x.f = y, v.push_back(x)
- Load: y = x.f
- Call: r = x.k(a...)
- 需要分析的pointer
- local variables
- static field
- instance field
- array element: 这里忽视indexes,比如array[0]都抽象为array.arr
- 复杂的memory access会引入临时变量按照three-address code转化为简单的
Rules
Implementation
课件用图来形象表示相关的pointeres,当一个memory location x对应的pt(x)发生改变后,其对应的后续节点都要更新。
具体建图与语句种类的对应关系如下:
Algo
Differential Propagation
Pointer Analysis with Method Calls
就普通的把callgraph按照this,参数,return value彼此相连,因为是flow-insensitive的,所有实参都会连接到虚参的关系上。注意加的m.this就是指m方法的this这个placeholder节点,这个节点并不对应实际的存储空间,不过能代表对应关系,用来传递数据流。
Q: 不加PFG: x->m_this的影响?
经多方查证和询问,我还是认为和课件不同,加不加效果上都是一样的--所有x指向的objects最后都会传给mthis,如果硬要说加与不加有什么区别,也要在稍后的context insensitive时体现区别。
Q: 不同组的实参之间是否会相互影响?
1 class A {
2 static void main()
{ 3 A a = new A();
4 A b = new B();
5 A c = b.foo(a);
6 A d = b.foo(b);
7 }
8 A foo(A x) { ... }
9 }
10 class B extends A {
11 A foo(A y) {
12 return y;
13 }
14 }
- return y而非return r;
- 再加一句: A d = b.foo(c);
- 确实会混杂
- 本以为因为a,b没有直接调用,状态改变的时候图还没能建全,后来发现新的状态只是加入WL,还能再次往外推