When trying to understand what code does, it is often useful to create a graphical representation that shows how functions call each other. This kind of representation is often called a call graph.
Codeviz is a tool that helps create call graphs.
I downloaded codeviz from this website: http://www.csn.ul.ie/~mel/projects/codeviz/
Here is an example of a call graph for a function in gPXE:
The function name is in the rectangular box on the left, and all the functions that are called flow to the right. I have limited the display to 3 levels of depth for presentation purposes.
# Make sure we have graphviz and ncftp $ rpm -q graphviz ncftp # Fetch if needed $ sudo yum install graphviz ncftp $ wget http://www.csn.ul.ie/~mel/projects/codeviz/codeviz-1.0.11.tar.gz $ tar -xf codeviz-1.0.11.tar.gz $ cd codeviz-1.0.11 $ ./configure $ make $ sudo make install
The make
command above downloads and builds gcc-3.4.6 from ftp.gnu.org
.
It also installs genfull
and gengraph
in /usr/local/bin
.
To configure for gPXE you need to edit this line in src/Makefile.housekeeping:
PRECIOUS : $(BIN)/%.tmp
to be:
PRECIOUS : $(BIN)/%.tmp $(BIN)/%.cdepn
This causes .cdepn (C dependency) files to be kept.
First we get gccgraph to compile all the C files in gPXE. This is not too hard:
$ cd gpxe.git/src $ make veryclean $ make CC=/usr/local/gccgraph/bin/gcc blib
This will generate a .cdepn file for each .c file compiled. To see where they are do:
$ find . -name "*.cdepn"
Next we build the dependency database:
$ genfull
This creates the file full.graph
in the current directory.
To make a nice call graph of rtl8169_poll for instance
, we can do:
$ gengraph -f rtl8169_poll -d 3 output-font=Arial --output-layout LR --plain
This does a call graph of the function rtl8169_poll, depth 3, left-to-right orientation, and requests that output be saved for input to the dot
program.
dot
is the program that renders the outupt from gengraph:
$ dot -GPAPERSIZE=letter -Gsize=8,10.5 -Gcenter=1 -Gmargin=.25 -Tps -o rtl8169_poll.ps < rtl8169_poll.plain
dot
draws the call graph according to the instructions in the .plain
file, and outputs a file in whatever -T says (postscript in this case. png is also popular).
We can also request a .pdf
be created from the .ps
file using ps2pdf
:
$ ps2pdf rtl8169_poll.ps
The three commands can be wrapped in a shell script command called mkcg
such as:
#!/bin/sh gengraph -f ${1} -d 3 output-font=Arial --output-layout LR --plain dot -GPAPERSIZE=letter -Gsize=8,10.5 -Gcenter=1 -Gmargin=.25 -Tps -o ${1}.ps < ${1}.plain ps2pdf ${1}.ps rm ${1}.{ps,plain}
This makes the process of creating the .pdf
a single command:
$ mkcg rtl8169_poll
Ghostscript can combine separate PDF pages into a single file:
$ gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=gpxe-call-graphs.pdf gpxe-api-call-graphs/*.pdf