上下文敏感的指针分析
上下文敏感模型通过区分不同上下文的不同数据流来为调用建模,从而提高精确度。当前最熟知的上下文敏感策略是调用点敏感。每个调用点代表了一个调用栈。
基于复制
基于复制的方法是最直接的实现方式。
每个方法会被一个或多个上下文标识,其中的变量也会被上下文标识。而每创建一个上下文,方法和它的变量都会被复制一遍。
上下文敏感堆
在实际分析中,为了提高精度,我们为抽象对象也用上下文标识。最常用的策略是对象的上下文来自于创建它的方法
记号
- 上下文$c\in C$
- 上下文敏感方法$c:m\in C\times M$
- 上下文敏感变量$c:x\in C\times V$
- 上下文敏感对象$c:o_i\in C\times O$
- 字段$f\in F$
- 实例字段$c:o_i.f\in C\times O\times F$
- 上下文敏感指针$CSPointer = (C\times V)\cup (C\times O\times F)$
- 指向关系$pt: CSPointer\rightarrow P(C\times O)$
规则
New
i: x = new T()
的规则为
\[\overline{c:o_i\in pt(c:x)}\]在上下文$c$中,将$o_i$加入x指向对象集合中,其为无条件(必定)发生的。
Assign
x = y
的规则为
\[\underline{c^{'}:o_i\in pt(c:y)}\\ c^{'}:o_i\in pt(c:x)\]如果$o_i$在y的集合中,则加入同一上下文的x的集合中,即将y指向的对象集合在保留各自上下文的情况下加入x指向对象集合中。
Store
x.f = y
的规则为
\[\underline{c^{'}:o_i\in pt(c:x),c^{''}:o_j\in pt(c:y)}\\ c^{''}:o_j\in pt(c^{'}:o_i.f)\]即将y指向的所有对象加入同一上下文的x指向的每一个(有各自的上下文的)对象的f中。
Load
y = x.f
的规则为
\[\underline{c^{'}:o_i\in pt(c:x),c^{''}:o_j\in pt(c^{'}:o_i.f)}\\ c^{''}:o_j\in pt(c:y)\]即将x指向的每一个(有各自上下文的)对象的f加入和x相同上下文的y的指向集合中
Call
r = x.k(a1,...,an)
的规则为
\[c^{'}:o_i\in pt(c:x),m=Dispatch(o_i,k)\\ c^t=Select(c,l,c^{'}:o_i)\\ c^{''}:o_u\in pt(c:a_j),1\le j \le n\\ \underline{c^{'''}:o_v\in pt(c^t:m_{ret})}\\ c^{'}:o_i\in pt(c^t:m_{this})\\ c^{''}:o_u\in pt(c^t:m_{pj}),1\le j \le n\\ c^{'''}:o_v\in pt(c:r)\]在调用的时侯,要做五件事情:
- 根据$x$可能指向的对象和方法$k$得到调用的方法(集合)$m$
- 根据$m$、调用点$l$、调用对象选择一个被调用者上下文$c^t$
- 为每个方法$m$的上下文$c^t$传入$m$的this参数$m_{this}$
- 为每个方法$m$的上下文$c^t$传入第$j$个形参$m_{pj}$,值(集)为第$j$个实参的指向集合。
- 将每个方法$m$的上下文$c^t$的每个返回值$m_{ret}$加入r指向的对象集合。