我非常喜欢Julian Cohen's Contemporary Automatic Program Analysis talk中的这个幻灯片。简而言之,人们喜欢将程序分析分为静态和动态两大类。但实际上,从静态到动态、从手动到完全自动化,存在着广泛的程序分析技术谱系。符号执行是一种有趣的技术,介于静态和动态分析之间,并通常作为完全自动化方法应用。
静态分析是指对代码进行离线计算,以评估代码质量的任何计算过程。它可以应用于源代码、Java/C#等虚拟机代码或虚拟机指令集,甚至二进制目标代码。没有“一种”静态分析方法(尽管经典编译器控制和数据流通常作为SA的基础机制),该术语集体适用于可能在离线使用的所有类型的机制。符号执行是一种特定类型的离线计算,通过构建表示程序状态的公式来计算程序实际执行的某种近似值。之所以称其为“符号”,是因为该近似值通常是涉及程序变量及其值约束的某种公式。静态分析可能会使用符号执行并检查生成的公式。或者它可能使用其他技术(正则表达式、经典编译器流分析等)或某种组合。但静态分析不一定要使用符号执行。符号执行可能仅用于显示计算的预期符号结果。根据上述定义,这不是静态分析,因为没有形成关于该结果好坏的意见。或者,该公式可能会接受分析,此时它成为静态分析的一部分。从实际角度出发,人们可能使用其他程序分析技术来支持符号执行(“变量的此公式是否传递到读取变量x的哪些位置?”通常由流分析很好地回答)。您可以坚持认为静态分析是对源代码进行的任何离线计算,此时符号执行只是一个特例。我不认为这个定义有用,因为它不能很好地区分使用情况。