Search code examples
cfreestatic-analysis

which free tools can I use to generate the program dependence graph for c codes


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?


Solution

  • 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:

    PDG of main()

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