视频: 南京大学《软件分析》课程 08(Pointer Analysis
课程主页:Static Program Analysis | Tai-e (pascal-lab.net)
笔记参考:(34条消息) 【课程笔记】南大软件分析课程—16课时完整版_bsauce的博客-CSDN博客_南京大学软件分析
软件分析 - 知乎 (zhihu.com)
PPT: Pointer Analysis (nju.edu.cn)
Motivation
CHA 算法存在缺陷(上一节课有说)
上一节提到过 CHA 算法是针对 call site 的声明类寻找目标函数,所以如上图所示,n.get 的声明类是 Number,Number 有三个子类,所以找到的目标函数就是三个结果,但是这个结果是不准确的,所以我们需要用到指针分析,去寻找 call site 真正指向的那个函数。
Introduction to Pointer Analysis
指针分析
- 指针分析是基本的静态分析,用于计算一个指针可以指向的内存位置,对于面向对象程序来说是计算一个指针(变量或字段)可以指向哪些对象
- 指针分析是一种 may 分析,它的分析结果是可以指向的对象的集合
如上图的例子,指针分析得到的是指向关系(point-to relations)
指针分析和别名分析的区别
两个密切相关但不同的概念
指针分析: 指针可以指向哪些对象?
别名分析: 两个指针可以指向同一个对象吗?
别名信息可以从指向关系中获得
指针分析的应用
- 基本信息(别名分析/调用图)
- 编译优化(嵌入虚拟调用)
- 漏洞(空指针)
- 安全分析(信息流)
Key Factors of Pointer Analysis
指针分析是一个复杂的系统,许多因素都会影响指针分析的精度和效率
堆抽象
程序动态执行时,堆对象个数理论上是无穷无尽的,但静态分析无法处理这个问题。所以为保证指针分析可以终止,我们采用堆抽象技术,将无穷的具体对象抽象成有限的抽象对象。也即,将有共性的对象抽象成 1 个静态对象,从而限制静态分析对象的个数。
本节介绍的堆抽象技术是目前最常用的堆抽象技术——allocation-site 技术
- 原理:将动态对象抽象成它们的创建点(
Allocation-Site
),来表示在该点创建的所有动态对象。Allocation-Site
个数是有限的。
上下文敏感
- Context-sensitive:根据某函数调用上下文的不同,多次分析同一函数。
- Context-insensitive:每个函数只分析一次。
流敏感
- 流敏感
- 考虑语句顺序(控制流)的影响
- 流敏感会在每个程序点都保存一份指针指向关系映射
- 流不敏感
- 把程序当做无序语句的集合。
- 对整个程序保存一份指向关系映射
目前流敏感对 Java 提升不大,不过在 C 中很有效,本课程分析的是 Java,并且流不敏感技术相对简单,所以重点讨论流不敏感技术。
分析范围
- Whole-program 全程序:分析全程序的指向关系。
- Demand-driven 需求驱动:只分析影响特定域的指针的指向关系。
实际上现在大多是都是做的全程序的分析,因为需求分析分析的特定域中的指针可能依赖于其他域,所以需求分析计算指向关系最后的计算量可能不比全程序分析快多少。并且如果每一处需求都要进行一次计算,这些计算可能互相有重叠的地方,所以可能需求分析还会慢一点。
What Do We Analyze
主要集中于可以产生指向关系的语句
以 java 为例,有一下几种指针:
- Local variable:x
- Static field:C.f (有时候被称为全局变量)
- instance field:x.f(对象的 field)
- Array element:array[i] (静态分析往往没办法确定下标,一般是将整个 array 存到一个 field 中)如下图,就是创建了一个数组对象,存储和读取都是对这个对象进行的。
Static field 和 local varible 的分析方式一样,Array element 简化后和 instance field 相同,所以聚焦于第一种和第三种句子的分析。
直接影响到指针指向的语句
一般分为以下五种语句:
- New: x = new T()
- Assign: x = y
- Store: x.f = y
- Load: y = x.f
- Call: r = x.k(a,…)
- Static call C.get()
- Special call super.foo()
- Virtual call x.get ()