指针分析/Point-to Analysis/Reference Analysis

原创 2015年11月21日 10:44:23

目录

指针分析

指针分析紧接数据流分析,是静态分析中的一个难点。遗憾的是能把相关内容讲得通俗易懂的资料非常少,中文的更基本没有。所以我斗胆在这里以例子的形式讲一下静态分析中的指针分析。参考资料主要在.
如果有讲错的地方还望斧正。


指针分析的目的

对于任何一个指针/引用,能否在编译阶段就知道它会指向内存那块位置(位置在这里并不是0xFFFF这样的具体位置,而是说指向哪个stack/heap上local/object)呢?
通过把停机问题reduced to, 能证明指针问题是不可决定的。也就是不能对任何指针都准确的分析出它会确切指向哪。但这不妨碍我们求出近似解,从而在某些情况下能作出优化。
因此我们把问题转化为: 对于任何一个任何指针,能否在编译阶段知道它所有可能(may)指向的位置?
最简单的回答自然是不知道(top), 这种回答没有实际意义,我们要的是更”紧”的答案。

基础

因为我们关心的是指针所指向的位置,指针是一个变量,能改变变量值的命令只有赋值语句。
和C类似,我们定义有关指针的赋值语句见下表第一列:

赋值 约束 意义
a = &b
ab
bpts(a)
a = b
ab
pts(a)pts(b)
ba
a = *b
ab
vpts(b)|pts(a)pts(v)
*a = b
ab
vpts(a)|pts(v)pts(a)

先回顾下C中指针操作符的意义。’&’是取地址符,’*’是取值符。对于整形,它的值是个32位的整数; 那么指针的值是什么? 在程序运行时它也是一个数字,只是这个数字代表的内存的某块地址。在这里我们不关系心这具体地址是什么(也没法关心),我们研究的指针变量指向的是谁的地址。”谁”具体可以分为stack内存上局部变量,也可以是位于heap上的对象,在这里我们不作区分,统一抽象成一个变量,用小写字母表示。注意指针它本身也是变量,以上地址描述同样适用于它,指针分析难点正来于此。

因此指针p实际是一个集合(pts),它的元素是所有它可能指向的变量。所以不难理解表中前两行的约束和意义了: 当把变量b所在的地址赋值给a时,a可能指向的变量自然就包含了b的地址啦; 当b是指针时,把b的值赋值给a相当于把b所有可能的元素添加到a中。对于’*’我们要多分析一层,*b表示的是b中的每个元素。举个例子, 假设b = {p, q},那么*b指的就是p和q啦。so对于第三行相当于把p的值赋值给a且把q的值赋值给a, 也就是把集合p和q的所有元素添加到a里。第四行则是把(假设a = {i, j}) b赋值给i且也赋值给j, 也就是i和j都讲拥有b所有的元素。

同其它数据流分析一样,在分析时我们先把赋值语句转化成约束,在对约束求解不动点从而得出每个指针变量的值。

在进入求解不动点算法讲解前,先提一下什么是flow-insensitive。flow指的是控制流,对它不敏感代表语句的排列顺序对我们分析结果没有影响。我在这里讲得是flow-insensitive的分析。

Anderson 算法

本质上是个非常简单又很常用的workqueue(worklist)算法,只要会写宽度优先都能轻松实现。我们把表中第一行的赋值语句称为base语句,第二行的称为simple语句, 其余的称为complex。
先贴出来算伪代码:

// 代表指针的数据结构
class Pointer {
    final String sid;
    Set<Pointer> pts;
}

Set<Pointer> nodes; // 存储了代码片中出现的所有的指针变量,每个变量代表一个约束图的结点
init(nodes); // 依据上节表中第四列规则初始化图的边; 并把base和simple的结点初始化
Queue<Pointer> workQueue = new LinkedList<>(); 
for (Pointer node : nodes) {
    if (!node.pts.isEmpty()) {
        workQueue.add(node);
    }
}
while (!workQueue.isEmpty()) {
    Pointer v = workQueue.remove();
    for (Pointer a : v.pts) {
        for (Constraint constraint : constraints) {
            if (constraint.rightOp.star.contains(v)) {
                Pointer p = constarint.leftOp;
                // 添加a->p的边,如果边是新的则添加a至wq
                if (addEdge(a, p)) {
                    workQueue.add(a);
                } 
            } else if (constraint.leftOp.star.contains(v)) {
                Pointer q = constraint.rightOp;
                if (addEdge(q, a) {
                    workQueue.add(q);
                }
            }
        }
    }
    for (Edge edge : edges) {
        if (edge.from.equals(v)) {
            Pointer q = edge.to;
            int size = q.pts.size();
            q.pts.addAll(v.pts); 
            if (q.pts.size() != size) {
                workQueue.add(q);
            }
        }
    }   
}

通过不断添加边和结点内集合的元素直到图不再改变为止。因为union操作是单调的,lattice的元素是集合,因此能证明一定能求出不动点使得图不再改变。

例子

实例代码片 包含的赋值语句:
Base
p = &a
q = &b
r = &c
Simple
s = p
Complex
*p = q
t = *p
*s = r

图示

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

时间复杂度

N个结点,最多有O(N2)条边。每条边被引入时最多引入O(N)连带反应(e.g. a->b->c->d…, abcd..依次入队列),每条边最多引入一次, 所以复杂度是O(N3).


数据结构中的二级指针和引用

最近在复习《数据结构与算法》方面的知识,但是绝大多数数据结构的书籍都是以伪代码/类C语言的形式来描述算法的,当然也有少数C语言的版本。但是在C语言的算法描述中,由于C语言没有像C++一样的引用变量,因...
  • smtSoaringBird
  • smtSoaringBird
  • 2017年01月05日 15:45
  • 193

iOS开发之Xcode的静态分析(Static Code Analysis)与常见问题解决

iOS开发之Xcode的静态分析(Static Code Analysis)与常见问题解决 一.Xcode Analyze静态分析 Static Code Analysis Static Code...
  • wtdask
  • wtdask
  • 2016年06月16日 16:59
  • 1912

指针分析/Point-to Analysis/Reference Analysis

目录目录 指针分析 指针分析的目的 基础 Anderson 算法 例子 图示 指针分析指针分析紧接数据流分析,是静态分析中的一个难点。遗憾的是能把相关内容讲得通俗易懂的资料非常少,中文的更基本没有。所...
  • majestyhao
  • majestyhao
  • 2015年11月21日 10:44
  • 1725

C++引用

引用是变量的别名,不能只有别名 基本数据类型的引用: { int a=3; int &b=a;//引用必须初始化 b=10; cout } 结构体类型的引用 typedef ...
  • qq_41693486
  • qq_41693486
  • 2018年01月31日 19:32
  • 35

[概念] 价值分析(Value Analysis)/价值工程 (Value Engineering)

PMBOK (英 2004 3rd P110) 项目范围管理中的范围定义过程中有一种输入叫做产品分析(Product Analysis),其中提到了的分析工具有价值分析和价值工程,据课堂上老师介绍国内...
  • jameszhou
  • jameszhou
  • 2007年06月19日 00:21
  • 3354

LoadRunner--Analysis各项指标详解

一、常用到的性能测试术语 1.事务(Transaction) 在web性能测试中,一个事务表示一个“从用户发送请求->web server接受到请求,进行处理-> web server向D...
  • liangfengchang
  • liangfengchang
  • 2015年04月16日 08:55
  • 5361

iOS伪拷贝, 浅拷贝, 深拷贝

经常听说,浅拷贝拷贝地址,深拷贝拷贝内容,然后还有个什么伪拷贝,他们三个到底啥区别呀?...
  • Leo_DLi
  • Leo_DLi
  • 2016年03月20日 00:03
  • 547

深度长文教你彻底掌握C++/C指针

一.基础C++或者C里面最容易让人糊涂应该是指针了,不管是初学者甚至是有经验的童鞋有时候在用指针的时候也会出现一些很隐蔽的错误. 指针本身就是一个很绕的概念,而指针又能够和很多的结构比如数组(二维数...
  • xierhacker
  • xierhacker
  • 2016年09月13日 19:49
  • 8537

[ElasticSearch]分析之Analysis(分析)

分析(analysis)是将文本(如任何电子邮件的正文)转换为添加到倒排索引中进行搜索的tokens或terms的过程。 分析由分析器analyzer执行,分析器可以是内置分析器或者每个索引定制的自定...
  • SunnyYoona
  • SunnyYoona
  • 2017年05月22日 20:26
  • 1040

用Excel做What-If Scenario Analysis

What-If Scenario Analysis是一种根据各种假设条件来进行预测的方法,可以用于预测项目进度,这篇文章介绍了使用Excel中的What-If Analysis的功能来进行一个财务预测...
  • jameszhou
  • jameszhou
  • 2007年04月08日 23:41
  • 16434
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:指针分析/Point-to Analysis/Reference Analysis
举报原因:
原因补充:

(最多只允许输入30个字)