8

I'm writing a tool and I need to generate the callgraph for some C projects. I was able to generate the callgraph of one file using clang, but I was not able to find out how to generate the call graph across the whole project which contains tens of header and source files.

Any tool that can generate the callgraph to a file that can be parsed will be fine. A usable library will be better.

cipher
  • 129
  • 1
  • 8
  • Indirect calls through pointers to functions might make this a hard task. For the other calls, creating assembly code and processing that would be a way to achieve this using self-written scripts. – MvG Jul 26 '12 at 13:25
  • 1
    You've got a doxygen tag already - I believe it can dump callgraphs in XML... did you know? If so, can you explain what's wrong with it for your purposes? – Tony Delroy Jul 26 '12 at 13:28
  • @MvG this looks like a good idea – cipher Jul 26 '12 at 14:55
  • @Tony Yeah I know it can generate it in xml, but I wanted to know if there's a library that doxygen provides that I can use to automate this process without having the user to open doxygen and generate the files himself. – cipher Jul 26 '12 at 14:56
  • One more idea: `ld --gc-sections` must be doing some kind of call graph analysis as well. Not sure whether you can get a hook into that, but there might be a way. Probably won't really handle indirect calls either, but it might be able to decide when some code takes the address of a function so it might get called later. – MvG Jul 26 '12 at 15:58
  • @cipher: doxygen can be run as a command line utility - you could provide the right configuration and use `system()`... no user involvement required, no GUIs opening.... – Tony Delroy Jul 27 '12 at 00:58

2 Answers2

4

Also worth mentioning, the excellent GNU cflow:

GNU cflow analyzes a collection of C source files and prints a graph, charting control flow within the program.

GNU cflow is able to produce both direct and inverted flowgraphs for C sources. Optionally a cross-reference listing can be generated. Two output formats are implemented: POSIX and GNU (extended).

Input files can optionally be preprocessed before analyzing.

Edit
As for the library request. You might like to "tweak" output.c and instead of printing do something else with the data. The internal flow is organised into output handlers, so I think writing your own handler could already do the trick. It's not out of the box though.

hroptatyr
  • 4,702
  • 1
  • 35
  • 38
2

Turning my comment into an answer.

You can have a look at the assembly output and process that using a script. Assuming gcc on linux, you pass the -S flag to gcc and process the result with something like this:

perl -ne '/^([^. \t#].*):/ and $f=$1;/call\s+([^*]\S*)/ and print "$f -> $1\n";' *.S

This will give you a line for each static call, containing the calling and the called function. You could add a bit of boilerplate around that and feed the result to dot, or whatever you want to do with it.

You can omit the “must not start with a star” part of the regular expression to obtain some indication of indirect calls as well. You still won't be able to tell what functions will get called at that point, but at least you'll know that there is something more to know.

MvG
  • 57,380
  • 22
  • 148
  • 276
  • As you pointed out, this doesn't handle indirect function calls. – Ira Baxter Jul 26 '12 at 14:58
  • 3
    @IraBaxter, give me *any* solution which claims to handle indirect function calls, without *running* the application and recording actual calls, and I'll write an application which has a call that tool won't be able to predict. C pointers are black magic, you can do anything with them. – MvG Jul 26 '12 at 14:59
  • Whenever you build a static analyzer for code, you get a result which is limited in accuracy; it isn't "just pointers", it is the fact that you are processing a Turing machine. Yes, you can almost always fool it. For most of the code, you can get pretty reasonable answers or nobody would use static analysis tools. Go read about "conservative flow analyses." – Ira Baxter Jul 26 '12 at 15:11