1. gcov是什么?
注:程序概要分析工具是分析代码性能的工具。
2. gcov能做什么?
gcov可以统计
因此,gcov可以帮你优化代码,当然这个优化动作还是应该有开发者完成。
3. 如何使用gcov?
#include <iostream> using namespace std; int main() { int i,total; total = 0; for (i=0; i<10; i++) total += i; if (total != 45) cout << "Failure!" << endl; else cout << "Success!" << endl; return 0; }
3.1 使用gcov的3个阶段
(1) 编译
$ g++ -fprofile-arcs -ftest-coverage -o main main.cpp
$ ls
-rwxrwxr-x. 1 heli heli 20281 Dec 7 11:54 main -rw-rw-r--. 1 heli heli 217 Dec 7 10:57 main.cpp -rw-rw-r--. 1 heli heli 6632 Dec 7 11:54 main.gcno
-fprofile-arcs -ftest-coverage告诉编译器生成gcov需要的额外信息,并在目标文件中插入gcov需要的extra profiling information。因此,该命令在生成可执行文件test的同时生成mian.gcno文件(gcov note文件)。
(2) 收集信息
执行该程序,生成main.gcda文件(gcov data文件)。
(3) 报告
$ ./main Success! $ ll total 36 -rwxrwxr-x. 1 heli heli 20281 Dec 7 11:54 main -rw-rw-r--. 1 heli heli 217 Dec 7 10:57 main.cpp -rw-rw-r--. 1 heli heli 784 Dec 7 11:56 main.gcda -rw-rw-r--. 1 heli heli 6632 Dec 7 11:54 main.gcno$ gcov main.cpp File '/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/ios_base.h' Lines executed:0.00% of 2 /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/ios_base.h:creating 'ios_base.h.gcov' File '/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/ostream' Lines executed:0.00% of 11 /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/ostream:creating 'ostream.gcov' File '/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/basic_ios.h' Lines executed:0.00% of 10 /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/basic_ios.h:creating 'basic_ios.h.gcov' File 'main.cpp' Lines executed:88.89% of 9 main.cpp:creating 'main.cpp.gcov' File '/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/iostream' Lines executed:100.00% of 1 /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/iostream:creating 'iostream.gcov' File '/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/char_traits.h' Lines executed:0.00% of 2 /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/char_traits.h:creating 'char_traits.h.gcov' File '/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/locale_facets.h' Lines executed:0.00% of 5 /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/locale_facets.h:creating 'locale_facets.h.gcov'$ ll total 300 -rw-rw-r--. 1 heli heli 22753 Dec 7 11:57 basic_ios.h.gcov -rw-rw-r--. 1 heli heli 25834 Dec 7 11:57 char_traits.h.gcov -rw-rw-r--. 1 heli heli 44130 Dec 7 11:57 ios_base.h.gcov -rw-rw-r--. 1 heli heli 4084 Dec 7 11:57 iostream.gcov -rw-rw-r--. 1 heli heli 132403 Dec 7 11:57 locale_facets.h.gcov -rwxrwxr-x. 1 heli heli 20281 Dec 7 11:54 main -rw-rw-r--. 1 heli heli 217 Dec 7 10:57 main.cpp -rw-rw-r--. 1 heli heli 618 Dec 7 11:57 main.cpp.gcov -rw-rw-r--. 1 heli heli 784 Dec 7 11:56 main.gcda -rw-rw-r--. 1 heli heli 6632 Dec 7 11:54 main.gcno -rw-rw-r--. 1 heli heli 27743 Dec 7 11:57 ostream.gcov
生成:
main.cpp.gcov文件,该文件记录了每行代码被执行的次数。
main.cpp.gcov文件内容如下:
-: 0:Source:main.cpp -: 0:Graph:main.gcno -: 0:Data:main.gcda -: 0:Runs:1 -: 0:Programs:1 -: 1:#include <iostream> -: 2:using namespace std; 1: 3:int main() -: 4:{ -: 5: int i,total; 1: 6: total = 0; -: 7: 11: 8: for (i=0; i<10; i++) 10: 9: total += i; -: 10: 1: 11: if (total != 45) #####: 12: cout << "Failure!" << endl; -: 13: else 1: 14: cout << "Success!" << endl; 1: 15: return 0; 3: 16:}
3.2 gcov的选项
gcov的选项不多,也好理解,此处选3个典型的选项并结合例子加以说明。
(1) -a, --all-blocks
在.gcov文件中输出每个基本快(basic block)的执行次数。如果没有-a选项,则输出'main'函数这个block的执行次数,如上所示。使用该选项可以
Write individual execution counts for every basic block. Normally gcov outputs execution counts only for the main blocks of a line. With this option you can determine if blocks within a single line are not being executed.
# gcov -a main.cpp
$ gcov -a main.cpp File '/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/ios_base.h' Lines executed:0.00% of 2 /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/ios_base.h:creating 'ios_base.h.gcov' File '/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/ostream' Lines executed:0.00% of 11 /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/ostream:creating 'ostream.gcov' File '/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/basic_ios.h' Lines executed:0.00% of 10 /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/basic_ios.h:creating 'basic_ios.h.gcov' File 'main.cpp' Lines executed:88.89% of 9 main.cpp:creating 'main.cpp.gcov' File '/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/iostream' Lines executed:100.00% of 1 /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/iostream:creating 'iostream.gcov' File '/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/char_traits.h' Lines executed:0.00% of 2 /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/char_traits.h:creating 'char_traits.h.gcov' File '/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/locale_facets.h' Lines executed:0.00% of 5 /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/locale_facets.h:creating 'locale_facets.h.gcov'
main.cpp.gcov文件内容。
-: 0:Source:main.cpp -: 0:Graph:main.gcno -: 0:Data:main.gcda -: 0:Runs:1 -: 0:Programs:1 -: 1:#include <iostream> -: 2:using namespace std; 1: 3:int main() -: 4:{ -: 5: int i,total; 1: 6: total = 0; -: 7: 11: 8: for (i=0; i<10; i++) 1: 8-block 0 10: 8-block 1 11: 8-block 2 10: 9: total += i; -: 10: 1: 11: if (total != 45) 1: 11-block 0 #####: 12: cout << "Failure!" << endl; $$$$$: 12-block 0 -: 13: else 1: 14: cout << "Success!" << endl; 1: 14-block 0 1: 15: return 0; 1: 15-block 0 3: 16:} 1: 16-block 0 1: 16-block 1 1: 16-block 2 1: 16-block 3
(2) -b, --branch-probabilities
在.gcov文件中输出每个分支的执行频率,并有分支统计信息。
# gcov -b main.cpp
(3) -c, --branch-counts
在.gcov文件中输出每个分支的执行次数。
# gcov -c main.cpp