which free tools can I use to generate the program

2019-03-11 07:45发布

问题:

I want to generate a Program Dependence Graph (PDG) from C source code. I found papers that explain how do it, but all used the commercial CodeSurfer tool.

Are there any free tools or open source projects that can do this job?

回答1:

Frama-C is an Open Source static analysis platform with a slicer for C programs based on the computation of a Program Dependence Graph.

Note that slicing actual programs written in a real programming language such as C involves many special cases and concepts that are skimmed over in scientific publications. Still, I am confident that you won't find anything simpler than Frama-C's PDG computation, first because it is the only Open Source one available (that I know of), and second because any other PDG computation that handled C programs would have to solve the same problems and introduce the same concepts.

Here is one example:

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);
}

The command frama-c -pdg -pdg-dot graph -pdg-print t.c generates dot files graph.main.dot and graph.f.dot containing the PDG of main() and f() respectively.

You can use the dot program to pretty-print one of them thus: dot -Tpdf graph.main.dot > graph.pdf

The result is below:

Note the edge from the node c = f(b); to the node *p = 2;. A PDG computation claiming to be useful for C programs must handle aliasing.

On the other hand, a slicer using this PDG to slice on the criterion “inputs of statement c = f(b);” would be able to remove d = 3;, which cannot influence the function call, even through the pointer access *p. Frama-C's slicer uses the dependencies indicated by the PDG to keep only the statements that are useful for the user-specified slicing criterion. For instance, the command frama-c -slice-wr c t.c -then-on 'Slicing export' -print produces the reduced program below, where the assignment to d has been removed:

/* 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;
}


回答2:

If you like to visualize the dependencies of methods calling each other and are using gcc then gcc's option -fdump-rtl-expand might be of interest to you.

For each source file you compile using the option -fdump-rtl-expand gcc will output a *.expand file.

Those files fed to the tool egypt produce graph(s) showing the method's dependencies.