Next: Output Formats, Previous: Quick Start, Up: Top
In the previous chapter we have discussed direct graphs, displaying caller—callee dependencies. Another type of cflow output, called reverse graph, charts callee—caller dependencies. To produce a reverse graph, run cflow with --reverse (-r) command line option. For example, using a sample whoami.c:
$ cflow --reverse whoami.c fprintf(): who_am_i() <int who_am_i (void) at whoami.c:8>: main() <int main (int argc,char **argv) at whoami.c:26> main() <int main (int argc,char **argv) at whoami.c:26> getenv(): who_am_i() <int who_am_i (void) at whoami.c:8>: main() <int main (int argc,char **argv) at whoami.c:26> geteuid(): who_am_i() <int who_am_i (void) at whoami.c:8>: main() <int main (int argc,char **argv) at whoami.c:26> getpwuid(): who_am_i() <int who_am_i (void) at whoami.c:8>: main() <int main (int argc,char **argv) at whoami.c:26> main() <int main (int argc,char **argv) at whoami.c:26> printf(): who_am_i() <int who_am_i (void) at whoami.c:8>: main() <int main (int argc,char **argv) at whoami.c:26> who_am_i() <int who_am_i (void) at whoami.c:8>: main() <int main (int argc,char **argv) at whoami.c:26>
This output consists of several subgraphs, each describing callers
for a particular function. Thus, the first subgraph tells that the
function fprintf
is called from two functions: who_am_i
and main
. First of them is, in turn, also called directly by
main
.
The first thing that draws attention in the above output is that
the subgraph starting with who_am_i
function is repeated several
times. This is verbose output. To make it brief, use
--brief (-b) command line option. For example:
$ cflow --brief --reverse whoami.c fprintf(): who_am_i() <int who_am_i (void) at whoami.c:8>: main() <int main (int argc,char **argv) at whoami.c:26> main() <int main (int argc,char **argv) at whoami.c:26> [see 3] getenv(): who_am_i() <int who_am_i (void) at whoami.c:8>: [see 2] geteuid(): who_am_i() <int who_am_i (void) at whoami.c:8>: [see 2] getpwuid(): who_am_i() <int who_am_i (void) at whoami.c:8>: [see 2] main() <int main (int argc,char **argv) at whoami.c:26> [see 3] printf(): who_am_i() <int who_am_i (void) at whoami.c:8>: [see 2] who_am_i() <int who_am_i (void) at whoami.c:8>: [see 2]
In brief output, once a subgraph for a given function is written, subsequent instances of calls to that function contain only its definition and the reference to the output line where the expanded subgraph can be found.
If the output graph is large it can be tedious to find out the required line number (unless you use Emacs cflow-mode, see Emacs). For such cases a special option --number (-n) is provided, which makes cflow begin each line of the output with a reference number, that is the ordinal number of this line in the output. With this option, the above output will look like:
$ cflow --number --brief --reverse whoami.c 1 fprintf(): 2 who_am_i() <int who_am_i (void) at whoami.c:8>: 3 main() <int main (int argc,char **argv) at whoami.c:26> 4 main() <int main (int argc,char **argv) at whoami.c:26> [see 3] 5 getenv(): 6 who_am_i() <int who_am_i (void) at whoami.c:8>: [see 2] 7 geteuid(): 8 who_am_i() <int who_am_i (void) at whoami.c:8>: [see 2] 9 getpwuid(): 10 who_am_i() <int who_am_i (void) at whoami.c:8>: [see 2] 11 main() <int main (int argc,char **argv) at whoami.c:26> [see 3] 12 printf(): 13 who_am_i() <int who_am_i (void) at whoami.c:8>: [see 2] 14 who_am_i() <int who_am_i (void) at whoami.c:8>: [see 2]
Of course, --brief and --number options take effect for both direct and reverse flow graphs.