【软件分析/静态程序分析学习笔记】3.数据流分析(Data Flow Analysis) (上):可达性分析(Reaching Definitions)

写在前面的话

本渣有幸成为南京大学软件学院研究生,在前往仙林校区蹭课的时候偶然发现了这门宝藏课程,听了以后感觉深有收获,但又因为课程难度较大,国庆假期归来发现遗忘较多,因此开了一坑来记录自己对每节课知识点的理解。也由于这是本人第一次开坑写博客,结构内容自有诸多不合理之处,希望有问题的地方大家可以指出。

上一篇文章中讲到了静态分析的中间表示,并引出了用于分析的控制流图,本文将依据控制流图讲述数据流分析的方法。由于数据流分析的方法难度较大,内容较多,将分为上下两篇讲述。


系列文章目录

1.静态程序分析(Static Program Analysis)介绍
2.中间表示(Intermediate Representation)
3.数据流分析(Data Flow Analysis) (上):可达性分析(Reaching Definitions)
4.数据流分析Data Flow Analysis) (下):存活变量分析(Live Variables Analysis)及可用表达式分析(Available Expressions Analysis)
5.数据流分析基础(Data Flow Analysis-Foundations)
6.过程间分析(Interprocedural Analysis)
7.指针分析(Pointer Analysis)入门
8.指针分析基础知识(Pointer Analysis Foundations)


一、什么是数据流分析

数据流分析主要研究数据流如何在控制流图中运行,即研究下面这张图。【软件分析/静态程序分析学习笔记】3.数据流分析(Data Flow Analysis) (上):可达性分析(Reaching Definitions)_第1张图片
这就是数据流分析的主要思想,研究特定的抽象符号代表的数据在特定环境中安全流动,这个环境主要研究控制流图中的传递函数和控制流处理。

不同的数据流分析拥有不同的抽象方法,不同的安全近似策略,不同的传递函数和不同的控制流处理方案。


二、控制流分析的知识预备

2.1 输入输出状态

先放张图帮助理解
【软件分析/静态程序分析学习笔记】3.数据流分析(Data Flow Analysis) (上):可达性分析(Reaching Definitions)_第2张图片
输入输出状态有两个性质:

  1. 每个输入/输出状态都与一个在IR块(可以理解为一个Basic Block)前/后的程序点相对应;
  2. 每一次IR块的执行,都会将一个旧的输入转换为一个新的输出。

我们会为每个程序点关联一个数据流值,这个值用来代表可观测到的程序数据集的抽象。(这句话比较抽象,后续会有具体示例)
数据流分析的目的是为所有语句的输入输出找到一组,基于控制流和传递函数的,安全的近似约束的解决方案。(依旧抽象,后续解释)

2.2 传递函数约束的表示方法

【软件分析/静态程序分析学习笔记】3.数据流分析(Data Flow Analysis) (上):可达性分析(Reaching Definitions)_第3张图片
如图是前向传播与反向传播的示例,前向传播即输出由输入根据IR块的传递函数决定的,反向传播同理。
【软件分析/静态程序分析学习笔记】3.数据流分析(Data Flow Analysis) (上):可达性分析(Reaching Definitions)_第4张图片
上图是一个对控制流分析过程的抽象表示。
第一句表示:后一句的输出等于前一句的输入
第二句表示:BB的输入等于第一句的输入,BB的输出等于最后一句的输出。
黄色句表示:前向传播的输出由输入经过运算获得,输入由指向自己的输出的union决定。
红色句表示:反向传播的输入由输出经过运算获得,输出由自己指向的输入的union决定。


三、Reaching Definitions Analysis

此节开始正式讲述数据流分析的应用,Reaching Definitions Analysis就是其中的一种分析方法。

3.1 Reach的定义(Reaching Definitions):

定义:
如果在程序中点p到点q构成一条路径,在点p处的定义d在这条路径中不会被杀死,则称定义d可以从点p reach 点q。

换句话说,就是:p处定义的变量v从点p可以 reach 点q,当且仅当,v在整个路径中不会获得新的定义。
【软件分析/静态程序分析学习笔记】3.数据流分析(Data Flow Analysis) (上):可达性分析(Reaching Definitions)_第5张图片
Reaching Definitions可以用来检测可能存在的、使用了未定义变量的情况。例如,在CFG入口为每个变量引入一个虚拟定义,如果这个虚拟定义能从入口reach一个使用了该变量的点p,那么这个变量就有可能未定义便被使用。(因为“未定义”reach了使用变量的p)

3.2 理解Reaching Definitions

3.2.1 怎么表示Reaching Definitions

【软件分析/静态程序分析学习笔记】3.数据流分析(Data Flow Analysis) (上):可达性分析(Reaching Definitions)_第6张图片
如图所示,可以使用bit编码表示在某程序点的多个Reaching Definitions,从左数第几个字节就是第几个definition,Di如果为0表示Di无法reach该程序点,Di如果为1表示Di可以reach该程序点。

3.2.2 如何理解D

D即Definition,可以表示为

D:v = x op y

一个D可以视为一行三地址码,做了两件事:

  1. 生成了一个定义D
  2. 在保持其他传入程序不受影响的同时,杀死了程序中其他对变量v的定义

所以对于对于BB而言可以得到以下传递函数:
【软件分析/静态程序分析学习笔记】3.数据流分析(Data Flow Analysis) (上):可达性分析(Reaching Definitions)_第7张图片
与此同时得到以下控制流函数:
【软件分析/静态程序分析学习笔记】3.数据流分析(Data Flow Analysis) (上):可达性分析(Reaching Definitions)_第8张图片
其中U表示union,结合前文使用bit字节表示的D,可以知道,IN[B]的输入等于OUT[P1]并OUT[P2],意味着只要存在一条路径可以reach,那么就算作可以reach。

3.2.3 Reaching Definitions的算法表示

【软件分析/静态程序分析学习笔记】3.数据流分析(Data Flow Analysis) (上):可达性分析(Reaching Definitions)_第9张图片
这便是Reaching Definitions的算法表示形式,其中入口和每个OUT都初始化为空集即00000的形式,是因为1并0或1都是1,会导致算法无法继续进行。
算法的停止条件是:经过一次完整的迭代后,迭代前后所有的OUT都不再发生改变。
接下来放一个分析过程,大家意会一下。
【软件分析/静态程序分析学习笔记】3.数据流分析(Data Flow Analysis) (上):可达性分析(Reaching Definitions)_第10张图片
可以看到OUT[B5]其实在第一次迭代后就达到了稳定值,但是因为这时静态分析,不像动态分析那样只看结果,所以要等到所有过程迭代后都不会变化才可以结束。
注释:BB块标号顺序的不同可能会导致达到稳定状态的迭代次数的不同,但是不会影响稳定状态的结果。并且经过简单的分析可以知道,迭代必会有一个最终的稳定状态,而不会一直循环迭代。


四、总结

以上就是本文的全部内容了,主要是介绍了数据流分析是什么,并首先介绍了一种数据流分析的算法。下一篇文章中将会介绍另外两种算法及一些总结内容。

你可能感兴趣的:(静态分析学习笔记,编程语言,1024程序员节)