sive and manually turn on certain features in the Doxyfile, which is Doxygen’s configuration file. These features
are listed in Table 2.
The option “HAVE_DOT” is the most
important one because it’s what allows
Doxygen to generate the most useful
output for the code spelunker, including class, collaboration, call, and caller
graphs. We’ll now take a brief look at
two of these types of graphs. The code
that we’re analyzing in this article is the
TCP/IP stack of the FreeBSD Operating
System. The BSD TCP/IP stack has been
studied in the past12 and continues to
be studied by researchers working on
the TCP/IP protocol suite.
For our examples we will look at a
single function, ip _ output(), which
is called in various parts of the network
figure 1. caller graph for ip_output().
stack in order to send an IP datagram to
the network. The ip _ output() function is quite important to the stack because all normal packet transmissions
flow through it. If a bug was found in
this function, or if the API needed to
be changed for some reason, it would
be important to trace back all of the
current users (callers) of the function.
In Figure 1 we see the caller graph produced by Doxygen for ip _ output().
In Figure 1 we see that no fewer
than 16 separate routines, in nearly as
many modules, depend on the ip _
output() function. To effect a fix or
update the API all of these routines
will need to be investigated. The red-bordered boxes in Figure 1 show nodes
that had a greater number of incoming
edges than could be shown comfort-
ably in the graph, which is a good indication that the function contained
therein is an important component of
the system.
The opposite of a caller graph is a
call graph. A call graph is more familiar
to users of the tools mentioned previously, such as Cscope and global, which
allow the user to interactively move
through the call graph of a function,
jumping into and out of underlying
functions while browsing the source
code. Doxygen gives us a different way
of interacting with the call graph. Figure 2 shows the call graph for the ip _
output() function.
The call graph, like the caller graph,
gives us a good visual overview of how
the function fits into the overall system.
Both of these figures function as maps
in_broadcast
icmp_reflect
iptime
ip_dooptions
in_rtalloc_ign
icmp_error
save_rte
ip_rtaddr
ip_forward
ip_srcroute
ip_ipsec_filtertunnel
in_canforward
ip_ipsec_mtu
ip_ipsec_fwd
icmp_send
ip_next_mtu
ip_ipsec_input
ip_output
ip_input
ip_reass
ip_freef
ip_mloopback
in_cksum
ip_fragment
ip_optcopy
ip_ipsec_output
in_localip
ip_insertoptions
in_delayed_cksum