注:程序概要分析工具是分析代码性能的工具。
2. gcov能做什么?
gcov可以统计
因此,gcov可以帮你优化代码,当然这个优化动作还是应该有开发者完成。
3. 如何使用gcov?
#include
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 <strong>main.gcdastrong>
- -rw-rw-r--. 1 heli heli 6632 Dec 7 11:54 <strong>main.gcnostrong>
$ ./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'
$ 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 <strong>main.cpp.gcovstrong>
- -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
$ 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
-: 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
-: 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