我想从C源代码生成程序依赖图(PDG)。我找到了解释它是怎么做的论文,但都使用了商业CodeSurfer工具。
是否有可以执行此任务的免费工具或开源项目?
答案 0 :(得分:17)
Frama-C是一个开源静态分析平台,a slicer for C programs基于程序依赖图的计算。
请注意,切割用实际编程语言(如C语言)编写的实际程序涉及许多在科学出版物中略过的特殊情况和概念。尽管如此,我相信你不会发现比Frama-C的PDG计算更简单的东西,首先是因为它是唯一可用的开源(我知道),其次是因为处理C程序的任何其他PDG计算都会有解决同样的问题并引入相同的概念。
以下是一个例子:
int a, b, d, *p;
int f (int x) {
return a + x;
}
int main (int c, char **v) {
p = &b;
a = 1;
*p = 2;
d = 3;
c = f(b);
}
命令frama-c -pdg -pdg-dot graph -pdg-print t.c
生成的点文件graph.main.dot
和graph.f.dot
分别包含main()
和f()
的PDG。
您可以使用dot
程序来打印其中一个:dot -Tpdf graph.main.dot > graph.pdf
结果如下:
请注意节点c = f(b);
到节点*p = 2;
的边缘。声称对C程序有用的PDG计算必须处理别名。
另一方面,使用此PDG对标准“语句c = f(b);
的输入”进行切片的切片器将能够删除d = 3;
,即使通过指针也不会影响函数调用访问*p
。
Frama-C的切片器使用PDG指示的依赖关系来仅保留对用户指定的切片标准有用的语句。例如,命令frama-c -slice-wr c t.c -then-on 'Slicing export' -print
生成下面的简化程序,其中d
的分配已被删除:
/* Generated by Frama-C */
int a;
int b;
int *p;
int f_slice_1(int x)
{
int __retres;
__retres = a + x;
return (__retres);
}
void main(int c)
{
p = & b;
a = 1;
*p = 2;
c = f_slice_1(b);
return;
}
答案 1 :(得分:4)
如果您希望可视化相互调用方法并使用gcc
的方法的依赖关系,那么gcc
的选项-fdump-rtl-expand
可能会引起您的兴趣。
对于使用选项-fdump-rtl-expand
gcc
编译的每个源文件,将输出*.expand
个文件。
提供给工具egypt的那些文件会生成显示方法依赖关系的图形。