Frama-C 代码切片器不加载任何 C 文件
Frama-C code slicer not loading any C files
我有一个 1000 行的 C 文件,其中包含 10 个由教授编写的数学算法,我需要从 1000 行中删除 9 个数学函数及其所有依赖项,所以我正在尝试使用 Frama-C Boron windows 二进制安装程序。
现在它不会加载最简单的 example.c 文件...我 select 源文件并且没有加载任何内容。
Boron 版本是 2010 年的,所以我检查了如何编译后来的 Frama-C:他们说在我的 windows 7 用户名中有一个 space 会导致问题,这并不令人鼓舞。
Frama-C 是我切片任务的最佳选择吗?
这是一个无法加载的示例文件:
// File swap.c:
/*@ requires \valid(a) && \valid(b);
@ ensures A: *a == \old(*b) ;
@ ensures B: *b == \old(*a) ;
@ assigns *a,*b ;
@*/
void swap(int *a,int *b)
{
int tmp = *a ;
*a = *b ;
*b = tmp ;
return ;
}
这是我希望仅从中提取一个函数的代码,标记为 smooth 和 swvd 的选项。 https://sites.google.com/site/kootsoop/Home/cohens_class_code
我查看了您链接到的代码,它似乎不是 Frama-C 分析的最佳候选者。例如,该代码并不严格符合 C99,使用例如一些 old-style 原型(包括隐式 int
return 类型),在没有前向声明的情况下定义之前使用的函数 (fft
),以及缺少的 header包含(stdlib.h
)。这些都不是大问题,因为更改相对简单,其中一些更改的处理方式与 gcc -std=c99
的工作方式类似:它们发出警告但不发出错误。但是,请务必注意它们确实需要 non-zero 时间,因此这不是 "plug-and-play" 解决方案。
更笼统地说,Frama-C 依赖 CIL (C Intermediate Language) 进行 C 代码规范化,因此切片程序可能与 "the original program minus the sliced statements" 不同。如果 objective 只是为了删除一些语句但在其他方面保持代码在语法上相同,那么 Frama-C 将不是理想的 1.
最后,值得注意的是,一些 Frama-C 分析可以帮助找到死代码,如果代码已经拆分为函数,结果会更加清晰。例如,在正确配置的程序上使用值分析,可以看到哪些 statements/functions 从未执行过。但这确实依赖于至少不存在某些未定义的行为。
例如如果你的程序中使用了未初始化的变量(C 标准禁止,但偶尔会发生并且未被注意到),值分析将停止其传播并且之后的代码可能被标记为死的,因为它是 语义上 已死 w.r.t。标准。意识到这一点很重要,因为幼稚的方法会产生误导。
总的来说,对于您提到的代码大小,我不确定 Frama-C 是否是一种 cost-effective 方法,尤其是如果 (1) 您从未使用过 Frama-C 并且是编译它时遇到问题(Boron 是一个非常老的版本,不推荐)和 (2) 如果您已经知道您的代码库,因此相对熟练地手动切片它的部分。
1就是说,我不知道有哪个 C 切片器可以保留这样的语句;我的观点是,虽然直觉上人们可能会认为 C 切片器会直接保留大部分语法,但 C 是一种如此曲折的语言,这样做非常困难,因此大多数工具会事先执行一些规范化步骤。
我有一个 1000 行的 C 文件,其中包含 10 个由教授编写的数学算法,我需要从 1000 行中删除 9 个数学函数及其所有依赖项,所以我正在尝试使用 Frama-C Boron windows 二进制安装程序。
现在它不会加载最简单的 example.c 文件...我 select 源文件并且没有加载任何内容。
Boron 版本是 2010 年的,所以我检查了如何编译后来的 Frama-C:他们说在我的 windows 7 用户名中有一个 space 会导致问题,这并不令人鼓舞。
Frama-C 是我切片任务的最佳选择吗?
这是一个无法加载的示例文件:
// File swap.c:
/*@ requires \valid(a) && \valid(b);
@ ensures A: *a == \old(*b) ;
@ ensures B: *b == \old(*a) ;
@ assigns *a,*b ;
@*/
void swap(int *a,int *b)
{
int tmp = *a ;
*a = *b ;
*b = tmp ;
return ;
}
这是我希望仅从中提取一个函数的代码,标记为 smooth 和 swvd 的选项。 https://sites.google.com/site/kootsoop/Home/cohens_class_code
我查看了您链接到的代码,它似乎不是 Frama-C 分析的最佳候选者。例如,该代码并不严格符合 C99,使用例如一些 old-style 原型(包括隐式 int
return 类型),在没有前向声明的情况下定义之前使用的函数 (fft
),以及缺少的 header包含(stdlib.h
)。这些都不是大问题,因为更改相对简单,其中一些更改的处理方式与 gcc -std=c99
的工作方式类似:它们发出警告但不发出错误。但是,请务必注意它们确实需要 non-zero 时间,因此这不是 "plug-and-play" 解决方案。
更笼统地说,Frama-C 依赖 CIL (C Intermediate Language) 进行 C 代码规范化,因此切片程序可能与 "the original program minus the sliced statements" 不同。如果 objective 只是为了删除一些语句但在其他方面保持代码在语法上相同,那么 Frama-C 将不是理想的 1.
最后,值得注意的是,一些 Frama-C 分析可以帮助找到死代码,如果代码已经拆分为函数,结果会更加清晰。例如,在正确配置的程序上使用值分析,可以看到哪些 statements/functions 从未执行过。但这确实依赖于至少不存在某些未定义的行为。
例如如果你的程序中使用了未初始化的变量(C 标准禁止,但偶尔会发生并且未被注意到),值分析将停止其传播并且之后的代码可能被标记为死的,因为它是 语义上 已死 w.r.t。标准。意识到这一点很重要,因为幼稚的方法会产生误导。
总的来说,对于您提到的代码大小,我不确定 Frama-C 是否是一种 cost-effective 方法,尤其是如果 (1) 您从未使用过 Frama-C 并且是编译它时遇到问题(Boron 是一个非常老的版本,不推荐)和 (2) 如果您已经知道您的代码库,因此相对熟练地手动切片它的部分。
1就是说,我不知道有哪个 C 切片器可以保留这样的语句;我的观点是,虽然直觉上人们可能会认为 C 切片器会直接保留大部分语法,但 C 是一种如此曲折的语言,这样做非常困难,因此大多数工具会事先执行一些规范化步骤。