[Source code analysis] dynamic analysis of C program function call relationships, source code functions
By Falcon of TinyLab.org
Reason
Source code analysis is an indispensable topic for programmers. Whether it is an open-source project or a variety of porting and development tasks at ordinary times, it cannot avoid in-depth interpretation of the source code.
To do well, you must first sharpen your tools.
I have already introduced how to use Callgraph to analyze the source code statically. Here I will introduce how to analyze the actual function execution status when the program is running. Considering the large differences between the application part and the kernel part, this article first introduces the application section.
This section mainly introduces three tools, one of which isgprof
And the other one isvalgrind
The other tool is used to export the results of the first two models to the dot imagegprof2dot
The function is similar to the one we introduced last time.tree2dotx
.
Preparation
Several related tools need to be prepared in advance.
Gprof2dot: converts the output from your profilers into a dot graph
$ sudo apt-get install python python-pip$ sudo pip install gprof2dot
Graphviz: dot format processing
$ sudo apt-get install graphviz
Gprof: display call graph profile data
$ sudo apt-get install gprof
Valgrind: a suite of tools for debugging and profiling programs
$ sudo apt-get install valgrind
After the tool is ready, a typical C program is saved as: fib. c.
#include <stdio.h>int fibonacci(int n);int main(int argc, char **argv){ int fib; int n; for (n = 0; n <= 42; n++) { fib = fibonacci(n); printf("fibonnaci(%d) = %dn", n, fib); } return 0;}int fibonacci(int n){ int fib; if (n <= 0) { fib = 0; } else if (n == 1) { fib = 1; } else { fib = fibonacci(n -1) + fibonacci(n - 2); } return fib;}
Gprof
Gprof is used to analyze code execution in the runtime of an application.
It needs to use the source code-pg
Compile and run:
$ gcc -pg -o fib fib.c$ ./fib
After running, a log file is generated:
$ ls gmon.outgmon.out
It can be analyzed as follows:
$ gprof -b ./fib | gprof2dot | dot -Tsvg -o fib-gprof.svg
Viewfib-gprof.svg
As follows:
In addition to the call relationship, this chart also shows the number of executions and percentage of each function.
Valgrind s callgrind
Valgrind is an open-source tool for performance analysis. It can be used not only to check memory leakage and other problems, but also to generate function call diagrams.
Valgrind does not depend on-pg
Compilation options, which can be compiled and run directly:
$ gcc -o fib fib.c$ valgrind --tool=callgrind ./fib
Then a log file is displayed:
$ ls callgrind*callgrind.out.22737
Then usegprof2dot
Analysis:
$ gprof2dot -f callgrind ./callgrind.out.22737 | dot -Tsvg -o fib-callgrind.svg
Viewfib-callgrind.svg
As follows:
Valgrind extracts more information than gprof, including the parent function of the main function.
However, Valgrind actually provides more information-n0 -e0
Remove the execution percentage limit. All executed items are displayed as follows:
$ gprof2dot -f callgrind -n0 -e0 ./callgrind.out.22737 | dot -Tsvg -o fib-callgrind-all.svg
The result is as follows:
All calls are displayed. The hotspot call Branch is marked in red. Because in fact, many other things are done behind a program running, such as dynamic symbolic links andmain
The actual Code also callsprintf
, Although the proportion is very low.
Considering that the above results are too many, it is not easy to analyze. If you only want to care about the call of a functionmain
For example, you can:
$ gprof2dot -f callgrind -n0 -e0 ./callgrind.out.22737 --root=main | dot -Tsvg -o fib-callgrind-main.svg
It must be noted that, apart fromgprof2dot
,kcachegrind
It can also be used to displayValgrind's callgrind
Data:
$ sudo apt-get install kcachegrind$ kcachegrind ./callgrind.out.22737
PassFile --> Export Graph
You can export call graphs. Only a graphical tool, a command line, andkcachegrind
You cannot display all branches at a time, but you can flexibly view them one by one.
Summary
The above shows the actual execution path of the source code from the runtime perspective. Currently, it only goes deep into the function layer.
The result is slightly different from the previous static analysis.
- In actual operation, the number of calls of different branches varies, and even some branches may not be executed at all. These data provide a hot spot for us to optimize performance.
- In actual operation, we observe that apart from some functions in the Code, there are also
main
And even library functions suchprintf
Provides us with a way to understand the details behind the program.
This article only introduces the application section (actually the user space when the program runs). Next we will analyze which kernel interfaces (system calls) are called when an application is executed, the execution of those interfaces and the function calls that go deep into the kernel space.