软件分析笔记:1.软件分析基础

本文是对于北京大学熊英飞老师《软件分析》课件以及南京大学李樾老师《软件分析》课程视频的总结。

1.哥德尔不完备定理及其在软件分析中应用

1.1定理内容

对任意能表示自然数的系统,一定有定理不能 被证明

1.2定理应用

主流程序语言的语法+语义=能表示自然数的形式系统 。

哥德尔不完备定理在处理内存泄露判定问题时的应用

设有表达式T不能被证明

a=malloc() 
if (T) free(a); 
 return; 

若T为永真式,则没有内存泄露,否则就可能有。

2.停机问题

2.1停机问题内容

停机问题的实质是判断一个程序在给定输入上是否会终止 ,不存在一个算法能回答停机问题。

2.2停机问题实例

假设存在停机问题判断算法:bool Halt(p) ,p为特定程序,给定某邪恶程序

   void Evil() {
	  if (!Halt(Evil)) return; 
	  else while(1);
  }

Halt(Evil)的返回值是什么?

• 如果为真,则Evil不停机,矛盾

• 如果为假,则Evil停机,矛盾

2.3一个检查停机问题的算法

当前系统的状态为内存和寄存器中所有Bit的值 ,给定任意状态,系统的下一状态是确定的 。令系统的所有可能的状态为节点,状态A可达状态B 就添加一条A到B的边,那么形成一个有向图(有限 状态自动机),如果从任意初始状态出发的路径都无环,那么系统 一定停机,否则可能会死机 ,给定起始状态,遍历执行路径,同时记录所有访问过的状 态。 如果有达到一个之前访问过的状态,则有环。如果达到终 态,则无环。 因为状态数量有穷,所以该算法一定终止。

3.可判定问题

判定问题(Decision Problem):回答是/否的问题

可判定问题(Decidable Problem)是一个判定问题,该问题存在一个算法,使得对于该问题的每 一个实例都能给出是/否的答案。

停机问题是不可判定问题

4.莱斯定理(Rice’s Theorem)

4.1定理内容

我们可以把任意程序看成一个从输入到输出上的 部分函数(Partial Function),该函数描述了程序的行为 。

关于程序行为的任何非平凡属性,都不存在可以 检查该属性的通用算法

  • 平凡属性:要么对全体程序都为真,要么对全体程序 都为假
  • 非平凡属性:不是平凡的所有属性
  • 关于程序行为:即能定义在函数上的属性
  • 特别注意莱斯定理的适用条件是关于程序行为而不是结构,并且不适用莱斯定理的也未必可判定。例如程序使用了多少个变量,就是涉及程序结构的问题,所以像[确定程序使用的变量是否多于50个]这样的问题无法用莱斯定义来说明它是不是不可判定的。

4.2莱斯定理的证明

反证法:给定函数上的性质P,因为P非平凡,所以一定存在程序使 得P满足,记为ok_prog。假设检测该性质P的算法为P_holds

编写如下函数来检测程序p是否停机

   Bool halt(Program p) { 
	  void evil(Input n) { 
		  Output v = ok_prog(n); 
		  p(); 
		  return v;
   }
   return P_holds(evil);
  }

如果P_holds存在,则我们有了检测停机的算法

5.近似法

5.1定义

近似法:允许在得不到精确值的时候,给出不精确的答案。对于判断问题,不精确的答案就是不知道。

近似求解判定问题:输出“是”、“否”或者“不 知道”,我们的目标就是尽可能多的回答“是”、“否”,尽可能少的回答“不知道”。

5.2分类

假设正确答案是一个集合S

  • must分析:返回的集合总是S的子集

  • may分析:返回的集合总是S的超集

must和may的区分并不严格,可以互相转换 ,可以将判定问题取反,或者队友返回集合的问题,将返回值定义为原集合的补集。

6.安全性

在编译器优化中,我们需要保证决定不改变程序的语义 。安全性就是根据分析结果所做的优化绝对不会改变程序语义 。安全性的定义和具体应用场景有关,但往往对应于 must分析和may分析中的一个 。安全性有时也被成为健壮性(soundness)、正确性 (correctness) 。 健壮性的反面有时也被成为完整性(completeness) ,如果健壮性对应must-analysis,则完整性对应may-analysis。

猜你喜欢

转载自www.cnblogs.com/crossain/p/12699484.html
今日推荐