Several methods for analyzing function call graph
Drawing a function call graph is useful for understanding large programs. I think we all had one. Read the source (and maintain a call stack in the mind), draw a function call relationship on paper, and then organize the experience of the diagram. If you're lucky, you can save some brainpower with the debugger's single-step tracking and call stack windows. However, if you want to analyze the script language code, it is likely to be honest with the first method. Wouldn't it be nice to have a call graph handy before you read the code? Here are a few of the free tools I know to analyze the function call relationships of C + +.
A function call graph is a graph (graph) and is a directed graph, mostly a no-loop graph (without a circle)-if there is no direct or indirect recursion in the code. Graphviz is a tool designed to draw both the graph and the graph, so many call graph analysis tools use it as the backend (back end). What about the front end? Just look at the recount of the family.
The analysis and analysis of call graph can be divided into "static" and "dynamic", so-called static analysis is to analyze the program without running, then the dynamic analysis is the actual operation of the recording program function call situation.
Static Analysis has two methods, one is to analyze the source code, and the second is to analyze the compiled target file.
The quality of the call graph that is obtained by analyzing the source depends on how well the analysis tool understands the programming language, such as the ability to find the correct overloaded C + + function. Doxygen is the source document tool, can also draw the call graph, it seems to be their own analysis of the source code to obtain a function call relationship. The GNU Cflow is a similar tool, but it seems to be biased toward the Analytical Flowchart (flowchart).
The best way to understand the programming language is the compiler, so someone came up with a patch for the compiler to record the function call relationship at compile time. Codeviz (a tool inspired by Martin Devera Devik) belongs to this category, and it (1.0.9) has patched gcc 3.4.1. Another tool Egypt the idea of a more ingenious, do not have to make a fuss to the compiler to patch, but let the compiler itself dump out the call relationship, and then analysis and analysis, to Graphviz to draw. But someone has to write a C language compiler (NCC), a special analysis of the call graph, the courage is commendable. If you do this to the C + + language, the cost is too high. Analyze the call graph of C + + or use the compiler to compare reality.
Analysis of the target file sounds very advanced, in fact, the work of the disassembly to binutils objdump to do, as long as the analysis of the disassembly of the text files on the line. Below is a partial result of objdump-d a.exe under Cygwin:
00401050 <_main>:
401050:55 Push%EBP
401051:89 e5 mov%esp,%ebp
401053:83 EC Sub $0x18,%esp
......
40107a:c7 movl $0x402000,0x4 (%ESP)
401,081:00
401082:c7 movl $0x402002, (%ESP)
401089:e8 F2 -xx-401180 <_fopen>
As you can see, main () calls fopen (). Codeviz with the ability to parse the target file.
Dynamic Analysis is a call to log a function while the program is running, and then organized into a call graph. Compared with static analysis, it can obtain more information, such as the sequence of function calls and the number of times, but there are some shortcomings, such as the application of some branches of the statement may not be executed, the functions called in these branches are naturally not recorded.
There are two methods for dynamic analysis, one is to use the call graph function of gprof (parameter- q), and the other is to utilize GCC -finstrument-functions
parameters.
The output generated by the gprof is as follows:
Index% time self children called name
0.00 0.00 4/4 Foo [4]
[3] 0.0 0.00 0.00 4 Bar [3]
-----------------------------------------------
0.00 0.00 Init [5]
0.00 0.00 Main [45]
[4] 0.0 0.00 0.00 2 Foo [4]
0.00 0.00 4/4 Bar [3]
-----------------------------------------------
0.00 0.00 1/1 Main [45]
[5] 0.0 0.00 0.00 1 Init [5]
0.00 0.00 Foo [4]
-----------------------------------------------
As you can see, bar () is called by Foo () 4 times, and Foo () is called once by Init () and main (), and Init () is called once by Main (). Using the Perl script to analyze the output of the gprof and generate the Graphviz dot input, you can draw the call graph. This script has been written by more than one person: http://www.graphviz.org/Resources.php,http://www.ioplex.com/~miallen/.
The purpose of the -finstrument-functions parameter of GCC is to add hooks to the program to invoke each of the following functions at each entry and Exit Function:
void __cyg_profile_func_enter( void *func_address, void *call_site )
__attribute__ ((no_instrument_function));
void __cyg_profile_func_exit ( void *func_address, void *call_site )
__attribute__ ((no_instrument_function));
Of course, the two functions themselves cannot be hooked (using the no_instrument_function __attribute__), or they will never be exhausted:) Here is the function address, need to use binutils in the Addr2line this gadget to convert to the function name, if it is a C + + function, but also use c++filt name Demangle. Specific methods in the " use Graphviz visual function call" in detail, here no longer repeat.
From the adaptability, the source code analysis is the strongest, even if there is grammatical error in the source code, the head file is not all right, it can still analyze a sorta. Compiler-based analysis of the requirements of the source code is higher, at least can be compiled through (gcc parameter-c)-can produce an object file, not necessarily linked to the executable file. This requires at least no syntax error in the source code, where the function called is not necessarily defined (definition), but there is a declaration (declaration), that is, the header file to complete. Of course, it's really not all right, I put a few function declarations in front can fool the compiler:) As for dynamic analysis, the highest requirement-the program needs to be run. If you are analyzing a certain part of the operating system, such as memory management or the network protocol stack, then the two dynamic analysis methods mentioned here are probably not applicable.
I found that almost all of the free tools listed above are unrelated to GCC, GNU binutils. Here we are sorting them out and drawing them with Graphviz:
Several methods for analyzing function call graph