让 Frama-c 显示 "dead branches" 的依赖关系

Make Frama-c show dependencies even of "dead branches"

我正在使用 frama-c Aluminium-20160502 版本,我想找出一个大程序中的依赖项。在命令行中使用选项 -deps 时,我发现缺少一些依赖项。特别是当几个条件加入一个 if 时,只要一个条件为假,依赖分析就会停止。在这个例子中:

#include<stdio.h>
#include<stdbool.h>

/*Global variable definitions*/
bool A = true;
bool B = false;
bool C = true;
bool X;
bool Y;

bool res;


void main(){

        if (A && B && C) {
                res = X;
        }else res = Y;
}

当我尝试时:frama-c -deps program.c

frama 显示以下依赖项:

[来自] ====== 计算的依赖关系 ======

这些依赖关系在终止的执行终止时保持:

[from] 主要功能: 来自 A 的资源; B; Y

[来自] ====== 依赖关系结束 ======

所以它没有达到条件C,因为B已经是假的。

我想知道是否有办法告诉 frama 计算所有依赖项,即使条件不满足也是如此。我尝试使用选项 -slevel 但没有结果。我知道有一种方法可以使用间隔 Frama_C_interval(0,1) 但是当我使用它时,使用此函数的变量未显示在依赖项中。我想让 X 和 Y 依赖于 A、B、C 和 res 依赖于 A、B、C、X、Y

有什么想法吗?

From 插件使用值分析插件的结果。在您的示例中, AB 的值足够精确,以至于 Value 能够推断出条件已完全确定(因为 && 运算符是从左到右延迟计算的) 在达到 C 之前,因此 C 永远不会影响结果,因此从 From.

的角度来看不是依赖项

不幸的是,Frama_C_interval 不能直接在全局初始化器中使用:

user error: Call to Frama_C_interval in constant.

但是,您可以使用 "hack"(不一定是最佳解决方案,但在这里有效):

volatile bool nondet;
bool A = nondet;
bool B = nondet;
bool C = nondet;
...

请注意,因为 nondetvolatile,每个变量 ABC 都分配了不同的非确定性值。

在这种情况下,Value 必须考虑条件的两个分支,因此 C 在您的示例中成为依赖项,因为在执行期间可能会读取 C main。然后你将拥有:

       These dependencies hold at termination for the executions that terminate:
[from] Function main:
  res FROM A; B; C; X; Y

请注意,某些插件在处理可变变量时需要特殊处理,因此这并不总是最佳解决方案。

然而,这只处理某些类型的依赖关系。正如 Value Analysis user manual 的第 6 章所述,From 插件计算功能、命令和操作依赖性。这些 包括间接 控制依赖项 ,如您提到的 X from A, B, C。对于那些,您需要 PDG(程序依赖关系图)插件,但它目前没有依赖关系的文本输出。您可以使用 -pdg 来计算它,然后 -pdg-dot <file> 以点 (graphviz) 格式导出依赖关系图。这是我为您的 main 函数(使用前面提到的 volatile hack)得到的结果:

最后,附带说明:-slevel 主要用于 提高 精度,但在您的示例中,您已经 太多了 精度(即,Value 已经能够推断出 C 从未在 main 中读取)。