Next: Direct and Reverse, Previous: Intro, Up: Top
Let's begin our acquaintance with the GNU cflow utility with an example. Suppose you have a simple implementation of whoami command and you wish to obtain a graph of function dependencies. Here is the program:
/* whoami.c - a simple implementation of whoami utility */ #include <pwd.h> #include <sys/types.h> #include <stdio.h> #include <stdlib.h> int who_am_i (void) { struct passwd *pw; char *user = NULL; pw = getpwuid (geteuid ()); if (pw) user = pw->pw_name; else if ((user = getenv ("USER")) == NULL) { fprintf (stderr, "I don't know!\n"); return 1; } printf ("%s\n", user); return 0; } int main (int argc, char **argv) { if (argc > 1) { fprintf (stderr, "usage: whoami\n"); return 1; } return who_am_i (); }
Running cflow produces the following output:
$ cflow whoami.c main() <int main (int argc,char **argv) at whoami.c:26>: fprintf() who_am_i() <int who_am_i (void) at whoami.c:8>: getpwuid() geteuid() getenv() fprintf() printf()
This is a direct call graph showing caller—callee dependencies in the input file. Each line starts with a function name, followed by a pair of parentheses to indicate that it is a function. If this function is defined in one of the input files, the line continues by displaying, within a pair of angle brackets, a function signature and the location of its definition. If the function calls another functions, the line ends with a colon. For example, the line
main() <int main (int argc,char **argv) at whoami.c:25>:
shows that function main
is defined in file whoami.c
at line 25, as int main (int argc, char **argv)
. Terminating
colon indicates that main
invokes other functions.
The lines following this one show which functions are called by
main
. Each such line is indented by fixed amount of white space
(by default four spaces) for each nesting level.
Usually cflow prints a full function signature. However, sometimes you may wish to omit some part of it. Several options are provided for this purpose. To print signatures without function names, use --omit-symbol-names option. To omit argument list, use --omit-arguments. These options can be needed for a variety of reasons, one of them being to make the resulting graph more compact. To illustrate their effect, here is how would the first line of the above graph look if you had used both --omit- options:
main() <int () at whoami.c:25>:
By default, cflow starts outputting direct graph from
the function called main
. It is convenient when analyzing a set
of input files comprising an entire C
program. However, there
are circumstances where a user would want to see only a part of
the graph starting on particular function. Cflow
allows to select such function using --main (-m)
command line option. Thus, running
cflow --main who_am_i whoami.c
on the above file will produce following graph:
who_am_i() <int who_am_i (void) at whoami.c:8>: getpwuid() geteuid() getenv() fprintf() printf()