【静态分析】静态分析笔记06 - 指针分析介绍

参考:

【课程笔记】南大软件分析课程6——指针分析介绍(课时8) - 简书

-----------------------------------------------------------------------------------------

1. Motivation

指针分析必要性

2. 指针分析

目标:分析程序指针可以指向哪些内存。对于Java等面向对象语言,主要分析指针指向哪个对象。

说明:指针分析属于may analysis,分析的结果是某指针所有可能指向哪些对象,是个over-approximation集合。

示例:面向对象语言中的指针指向问题。对于setB()函数,this指向new A(),因为是调用者是a.setB();setB()中的b是x传过来的,所以b指向new B()。

区别

  • 指针分析:分析指针所有可能指向的对象。
  • 别名分析:分析两个指针是否指向相同的对象,可通过指针分析来推导得到。

应用:基本信息(别名分析/调用图),编译优化(嵌入虚拟调用),漏洞(空指针),安全分析(信息流)。

3. 影响指针分析的关键要素

指标:精度(precision)& 效率(efficiency)。

影响因素:本课程,我们主要分析分配点的堆抽象技术、上下文敏感/不敏感、流不敏感、全程序分析。

因素 问题 选项
Heap abstraction 如何建模堆内存? Allocation-site • Storeless
Context sensitivity 如何建模调用上下文? Context-sensitiveContext-insensitive
Flow sensitivity 如何建模控制流? • Flow-sensitive • Flow-insensitive
Analysis scope 分析哪部分程序? Whole-program • Demand-driven

(1)堆抽象(内存建模)

问题:程序动态执行时,堆对象个数理论上是无穷无尽的,但静态分析无法处理这个问题。所以为保证指针分析可以终止,我们采用堆抽象技术,将无穷的具体对象抽象成有限的抽象对象。也即,将有共性的对象抽象成1个静态对象,从而限制静态分析对象的个数。

技术概览

我们只学习Allocation-Site技术,最常见也最常被使用。

Allocation-Site原理:将动态对象抽象成它们的创建点(Allocation-Site),来表示在该点创建的所有动态对象。Allocation-Site个数是有限的,因为程序是有限的。

示例:循环创建了3个对象,我们用O2来抽象表示这3个动态对象。

(2)上下文敏感 Context Sensitivity

问题:考虑是否区分不同call-site(调用点)对同一函数的调用。

  • Context-sensitive:根据某函数调用上下文的不同,多次分析同一函数。
  • Context-insensitive:每个函数只分析一次。

(3)流敏感 Flow Sensitivity

问题:考虑语句顺序(控制流)的影响 vs 把程序当做无序语句的集合。

方法:流敏感会在每个程序点都保存一份指针指向关系映射,而流不敏感则对整个程序保存一份指向关系映射。

说明:目前流敏感对Java提升不大,不过在C中很有效,本课程分析的是Java,所以重点讨论流不敏感技术。

指针分析示例

(4)分析范围 Analysis Scope

问题:分析程序的哪一部分?

  • Whole-program 全程序:分析全程序的指向关系。
  • Demand-driven 需求驱动:只分析影响特定域的指针的指向关系。

4. 分析哪些语句

问题:哪些语句会影响指针指向,那就只分析这些语句。

Java指针类型

  1. Lacal variable: x

  2. Static field:C.f (有时称为全局变量)

  3. Instance field: x.f (对象的field)

  4. Array element: array[i] ——因为静态分析无法确定下标,所以将array中所有成员映射到一个field中,等价于Instance field。如下图所示:

影响指针指向的语句

  1. New: x = new T()
  2. Assign:x = y
  3. Store: x.f = y
  4. Load: y = x.f
  5. Call: r = x.k(a,...)
    • Static call: C.foo()
    • Special call: super.foo() / x.<init>() / this.privateFoo()
    • Virtual call:x.foo()

复杂的内存访问可以通过引入临时变量,转化为三地址代码:

x.f.g.h = y;
// 转化为
t1 = x.f;
t2 = t1.g;
t2.h = y;

相关推荐

  1. 【Webpack】TreeShaking与静态分析

    2024-04-23 18:06:01       34 阅读
  2. Hive动态分区静态分区

    2024-04-23 18:06:01       45 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-23 18:06:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-23 18:06:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-23 18:06:01       87 阅读
  4. Python语言-面向对象

    2024-04-23 18:06:01       96 阅读

热门阅读

  1. PHP 判断文件是否存在

    2024-04-23 18:06:01       33 阅读
  2. 汇编期末复习知识点

    2024-04-23 18:06:01       38 阅读
  3. 在Linux系统中,如何查看当前登录的用户

    2024-04-23 18:06:01       36 阅读
  4. DreamFusion都在什么地方用

    2024-04-23 18:06:01       36 阅读
  5. 【LeetCode热题100】【链表】合并 K 个升序链表

    2024-04-23 18:06:01       35 阅读
  6. GB4806.13食品接触复合材料广东实验室

    2024-04-23 18:06:01       36 阅读
  7. 基础技术(MapStruct、SPI、TK-Mybatis)

    2024-04-23 18:06:01       38 阅读
  8. Swift网络编程

    2024-04-23 18:06:01       41 阅读
  9. Swift中日期的相互转换

    2024-04-23 18:06:01       35 阅读
  10. swift 侧滑返回

    2024-04-23 18:06:01       34 阅读
  11. 代码随想录训练营23day-贪心算法

    2024-04-23 18:06:01       42 阅读
  12. CSS系列:伪类选择器小记

    2024-04-23 18:06:01       40 阅读