concov ã®ããã¥ã¡ã³ããæ¸ããã¨æã£ãããã©ãä½ããæ¸ããå°ã£ãã®ã§ãã¨ãããããã®åã« gcov ã®ä½¿ãæ¹ã¨ã¯ã¾ãã©ãããæ¸ãã¦ã¿ã¾ãã
gcov ã¨ã¯
C è¨èªã§æ¸ãããããã°ã©ã ã®ã«ãã¬ãã¸ã測å®ãããã¼ã«ã§ããgcc ã«ä»å±ãã¦ãã¾ãã
åºæ¬çãªä½¿ãæ¹
ããããã³ã¼ããããã¨ããã
/* test.c */ #include <stdio.h> int foo(int x, int y) { return x + y; } int bar(int x, int y) { return x - y; } int main(void) { printf("%d\n", foo(2, 3)); printf("%d\n", foo(3, 4)); return 0; }
ã³ã³ãã¤ã«ããã-coverage ãã¤ãã㨠gcov ç¨ã®ãªãã¸ã§ã¯ããã¡ã¤ã«ãçæããã *1 ã
$ gcc -coverage -o test test.c
ãã㨠.gcno ã¨ããæ¡å¼µåã®ãã¡ã¤ã«ãçæããããããã«ã¯ (ãã¶ã) ã«ãã¬ãã¸ã®ãã°ã¨ã½ã¼ã¹ã³ã¼ãã®è¡çªå·ã¨ãã対å¿ãããããã®æ å ±ãå ¥ã£ã¦ãã
$ ls test test.c test.gcno
å®è¡ããã¨ã
$ ./test 5 7
ã«ãã¬ãã¸ã®ãã°ãè¨é²ãã .gcda ã¨ãããã¡ã¤ã«ãã§ããã
$ ls test test.c test.gcda test.gcno
gcov ãå®è¡ããã
$ gcov test.gcda File 'test.c' Lines executed:75.00% of 8 test.c:creating 'test.c.gcov'
ã«ãã¬ãã¸ã 75.00% ãªãã ãªã¼ã¨ãããã詳ããçµæ㯠test.c.gcov ã«ä¿åããã¦ããã
-: 0:Source:test.c -: 0:Graph:test.gcno -: 0:Data:test.gcda -: 0:Runs:1 -: 0:Programs:1 -: 1:/* test.c */ -: 2:#include <stdio.h> -: 3: 2: 4:int foo(int x, int y) { 2: 5: return x + y; -: 6:} -: 7: #####: 8:int bar(int x, int y) { #####: 9: return x - y; -: 10:} -: 11: 1: 12:int main(void) { 1: 13: printf("%d\n", foo(2, 3)); 1: 14: printf("%d\n", foo(3, 4)); 1: 15: return 0; -: 16:}
foo ã 2 åå¼ã°ãã¦ãã¨ããbar ãå¼ã°ãã¦ãªãã¨ããããã
ã½ã¼ã¹ã³ã¼ãã¨ãªãã¸ã§ã¯ããå¥ã®ãã£ã¬ã¯ããªã«ããå ´å
gcov ããã¡ã¤ã«ãè¦ã¤ããããªãã¦ã¨ã©ã¼ã«ãªããã¨ããã°ãã°ããã¾ãã
ä¾ãã°ãã½ã¼ã¹ã¯ src/ ã«ããªãã¸ã§ã¯ã㯠obj/ ã«ç½®ãå ´åã
/* src/foo.c */ int foo(int x, int y) { return x + y; }
/* src/bar.c */ int bar(int x, int y) { return x - y; }
/* src/main.c */ #include <stdio.h> int foo(int, int); int bar(int, int); int main(void) { printf("%d\n", foo(2, 3)); printf("%d\n", foo(3, 4)); return 0; }
.o ã obj/ 以ä¸ã«åºåããããã«ã³ã³ãã¤ã«ããã-coverage ã¯ã³ã³ãã¤ã«æã«ããªã³ã¯æã«ãã¤ããã
$ gcc -coverage -c -o obj/foo.o src/foo.c $ gcc -coverage -c -o obj/bar.o src/bar.c $ gcc -coverage -c -o obj/main.o src/main.c $ gcc -coverage -o test obj/foo.o obj/bar.o obj/main.o
.gcno ã obj/ 以ä¸ã«ã§ããã
$ ls obj bar.gcno bar.o foo.gcno foo.o main.gcno main.o
å®è¡ããã¨ã
$ ./test 5 7
.gcda ã obj/ 以ä¸ã«ã§ããã
$ ls obj bar.gcda bar.o foo.gcno main.gcda main.o bar.gcno foo.gcda foo.o main.gcno
gcov ã«ãããã¨ã°ã©ããã¡ã¤ã«ãè¦ããªãã¨ããããã
$ gcov obj/foo.gcda foo.gcno:cannot open graph file
ãã㧠cd obj ããã¨ãfoo.gcno ã¯è¦ã¤ããã®ã§ä¸å¿åããã© foo.c ãè¦ã¤ãããªãã®ã§ foo.c.gcov ã®è¡¨ç¤ºãå¤ã«ãªããªã©ã泥沼ã«ã¯ã¾ãã¾ãã
ã©ãããã°ãããã¨ããã¨ã
- gcov ã¯å¿ ã gcc ããã®ã¨åããã£ã¬ã¯ããªã§å®è¡ãã
- .gcno ã®ä½ç½®ã -o ãªãã·ã§ã³ã§æãã¦ãã
ã¨ãã¾ãã
$ gcov obj/foo.gcda -o obj File 'src/foo.c' Lines executed:100.00% of 2 src/foo.c:creating 'foo.c.gcov'
ã«ã¬ã³ããã£ã¬ã¯ããªã« foo.c.gcov ãåºæ¥ã¾ãã
-: 0:Source:src/foo.c -: 0:Graph:obj/foo.gcno -: 0:Data:obj/foo.gcda -: 0:Runs:1 -: 0:Programs:1 -: 1:/* src/foo.c */ 2: 2:int foo(int x, int y) { 2: 3: return x + y; -: 4:}
åãååã®ã½ã¼ã¹ã³ã¼ããå¥ã®ãã£ã¬ã¯ããªã«ããå ´å
ä¾ãã° src/core-module/foo.c 㨠src/sub-module/foo.c ããã£ãå ´åãã©ã¡ããã«ãã¬ãã¸ã®åºåã foo.c.gcov ã«ãªã£ã¦ãç¥ããªããã¡ã«ä¸æ¸ãããå¯è½æ§ãããã¾ãã
ã©ãããã°ãããã¨ããã¨ã
- gcov ã« -p ãªãã·ã§ã³ã渡ã
ã¨ãsrc#core-module#foo.c.gcov ã ã® src#sub-module#foo.c.gcov ã ã®ã¨ãã£ããã½ã¼ã¹ã®ãã¹ãã¨ã³ã³ã¼ãããæªãããã¡ã¤ã«åã«ãã¦ããã¾ãã
åãã½ã¼ã¹ãã¡ã¤ã«ãããããªã½ã¼ã¹ãã¡ã¤ã«ã« #include ããã¦ããå ´å
ä¾ãã° bar.c 㨠baz.c ãã #include "foo.h" ãã¦ããå ´åã
/* foo.h */ static int foo(int x, int y) { return x + y; }
/* bar.c */ #include "foo.h" int bar(int x, int y) { return foo(x, y); }
/* baz.c */ #include "foo.h" int baz(int x, int y) { return foo(x, y); }
ãã㧠bar.c ã®ã«ãã¬ãã¸ãè¦ããã¨ããã¨
$ gcov bar.gcda File 'foo.h' Lines executed:100.00% of 2 foo.h:creating 'foo.h.gcov' File 'bar.c' Lines executed:100.00% of 2 bar.c:creating 'bar.c.gcov'
ã¨ãªãããã®å¾ã§ baz.c ã®ã«ãã¬ãã¸ãè¦ããã¨ããã¨
$ gcov baz.gcda File 'foo.h' Lines executed:100.00% of 2 foo.h:creating 'foo.h.gcov' File 'baz.c' Lines executed:100.00% of 2 baz.c:creating 'baz.c.gcov'
ã¨ãªãã¾ããfoo.h.gcov ãæ¸ãã¤ã¶ããã¦ã¾ãããã㯠-p ãªãã·ã§ã³ãã¤ãã¦ãåé¿ã§ãã¾ããã
ã©ãããã°ãããã¨ããã¨ã
- gcov ã« -l ãªãã·ã§ã³ã渡ã
ã¨ãã¾ãã
$ gcov bar.gcda -l File 'foo.h' Lines executed:100.00% of 2 foo.h:creating 'bar.gcda##foo.h.gcov' File 'bar.c' Lines executed:100.00% of 2 bar.c:creating 'bar.gcda##bar.c.gcov' $ gcov baz.gcda -l File 'foo.h' Lines executed:100.00% of 2 foo.h:creating 'baz.gcda##foo.h.gcov' File 'baz.c' Lines executed:100.00% of 2 baz.c:creating 'baz.gcda##baz.c.gcov'
ã¨ããããã«ãgcda ãã¡ã¤ã«ã®ååãæåã«ã¤ãã®ã§ãä¸æ¸ããããã¨ã¯ãªããªãã¾ãã-l 㨠-p ãåããã¦ä½¿ããã¨ãã§ãã¾ãã
ã¾ã¨ã
gcov ã使ãã¨ãã®ãã¤ã³ãã
- gcc ã« -coverage ãã¤ãã¦ã³ã³ãã¤ã«ã»ãªã³ã¯ãã
$ gcc -coverage -o test test.c
- gcov 㯠gcc ããã®ã¨åããã£ã¬ã¯ããªã§å®è¡ãã
$ gcov foo.gcda
- .o ã .gcno ãå¥ã®ãã£ã¬ã¯ããªã«ããã¨ã㯠-o ãªãã·ã§ã³ã§ãã£ã¬ã¯ããªã示ã
$ gcov foo.gcda -o obj
- å¥ã®ãã£ã¬ã¯ããªã«åãååã®ã½ã¼ã¹ã³ã¼ããããã¨ã㯠-p ãã¤ãã
$ gcov foo.gcda -p
- ã½ã¼ã¹ã³ã¼ããè¤æ°ã®ã½ã¼ã¹ã³ã¼ããã #include ããã¦ããã¨ã㯠-l ãã¤ãã
$ gcov foo.gcda -l
以ä¸ã¯ concov ã¨é¢ä¿ãªã使ããç¥èã ã¨æãã¾ããã¡ãªã¿ã« concov ã§ä½¿ãå ´åã¯ãå ¨é¨ã® .gcda ãå¦çã㦠.gcov ãçæãã¦ãããããååãã¦éè¨ãã¦ãã¼ã¿ãã¼ã¹ã«çªã£è¾¼ãã®ã§ã.gcov ã®ä¸æ¸ããçºçããã¨ãã¼ã¿ã®æ¬ æã«ã¤ãªããã¾ãããã£ã¦ã¨ãããã -p -l ãã¤ããã¨ããã§ãã