Gå til hovedindhold
Version2 it for professionelle
Forsiden

Hovedmenu

  • It-nyheder
  • Blogs
  • It-job
  • It-firmaer
  • Whitepapers
  • Opret bruger
  • Log ind
Du kan logge ind med din e-mail-adresse
Der er forskel på store og små bogstaver i adgangskoden.
Glemt adgangskode?
Se kommentarer (3)
Emner Udviklingsværktøjer, Open source, Unix

Kode-værkstedet 2: GCC og kode-dækning

Af Peter Toft 30. december 2008 kl. 11:46

Som tidligere lovet vil jeg sætte mere fokus på nogle af de værktøjer på Linux (eller andre UNIX-varianter såsom FreeBSD/OpenBSD), som jeg har fået øjnene op for det sidste halve år. Et af de mere ukendte er C/C++ kode-dækning, som kan analyseres med GCC selv. Ideen er at oversætte al koden med nogle ekstra parametre, og ved kørsel skrives automatisk hvilke linier af koden, som eksekveres. Det har især relevant, hvis man har mange (f.eks. 100) test-scenarier, hvor man ikke kan overkomme f.eks. at debugge sig igennem dem alle. En god start er "man gcov", som indeholder en let læselig gennemgang af "code coverage" analyse med GCC.

Til eksempel har jeg lavet følgende kode "v2.c". Bemærk at jeg har indsat linienumre som bedre at kunne skrive om hvad der sker i koden. I kan selv hente koden fra Pastebin, hvis I vil have den rå kode.

1:#include
2: 3:int main(int argc, char **argv) 4:{ 5:
6: if (argc<2) 7: printf("ingen argumenter\n");
8: else
9: if (argc%2==1) 10: printf("et lige antal argumenter\n");
11: else 12: printf("et ulige antal argumenter\n");
13: 14: if (argc<=3) 15: printf("Højst to argumenter\n");
16: else 17: printf("Mere end to argumenter\n");
18:
19: return 0;
20:}

Normalt vil man oversætte koden med $ gcc -o v2 v2.c som giver den binære fil "v2" ud fra kildekoden "v2.c". Jeg laver med vilje ikke optimering af koden (-O2 eller -O3) for jeg vil netop ikke miste dele af koden.

Koden oversættes i stedet nu med $ gcc -o v2*** -fprofile-arcs -ftest-coverage*** v2.c

Eksempel er i den lette ende og det er let at se at programmet hopper ned i de forskellige løkker, alt efter antallet af argumenter til "v2" programmet. Første kørsel - uden argumenter. $ ./v2 ingen argumenter Højst to argumenter Som forventet kommer vi ned i linie 7 og linie 15 - vi kan se det på udskriften ovenfor.

Bemærk at allerede ved oversættelsen af programmet dannes en ny fil "v2.gcno", og når koden udføres skrives den egentlige database-fil "v2.gcda" med oversigt over hvad der har været udført.

Fordi koden blev oversat med "-fprofile-arcs -ftest-coverage", kan vi nu analysere kodedækningen (ud fra den ene kørsel af programmet). $ gcov v2.c File 'v2.c' Lines executed:60.00% of 10 v2.c:creating 'v2.c.gcov'

Ud kom "v2.c.gcov" - hvor 60% af de 10 effektive kodelinier har været udført. Lad os se på denne fil:

    -:    0:Source:v2.c
    -:    0:Graph:v2.gcno
    -:    0:Data:v2.gcda
    -:    0:Runs:1
    -:    0:Programs:1
    -:    1:#include        
    -:    2:
    -:    3:int main(int argc, char **argv)
    1:    4:{
    -:    5:                         
    1:    6:  if (argc&lt;2) 
    1:    7:    printf("ingen argumenter\n");     
    -:    8:  else           
#####:    9:    if (argc%2==1)
#####:   10:      printf("et lige antal argumenter\n");   
    -:   11:    else 
#####:   12:      printf("et ulige antal argumenter\n");    
    -:   13:
    1:   14:  if (argc&lt;=3)
    1:   15:    printf("Højst to argumenter\n");   
    -:   16:  else 
#####:   17:    printf("Mere end to argumenter\n");    
    -:   18:  
    1:   19:  return 0;              
    -:   20:}  

Det interessante er især linierne med hash-tegn foran - dvs. linie 10, 12 og 17 som endnu ikke er blevet udført. Vi kan med 1-tallerne foran bla. linie 7 se at de øvrige linier har været udført en gang. Det ser meget fint ud.

Lad os lige køre programmet et par gange mere (her dræber jeg lige tekst-output). $ v2 1 > /dev/null $ v2 1 1 > /dev/null Og igen køres gcov: $ gcov v2.c

    -:    0:Source:v2.c
    -:    0:Graph:v2.gcno
    -:    0:Data:v2.gcda
    -:    0:Runs:3
    -:    0:Programs:1
    -:    1:#include        
    -:    2:
    -:    3:int main(int argc, char **argv)
    3:    4:{
    -:    5:                         
    3:    6:  if (argc&lt;2) 
    1:    7:    printf("ingen argumenter\n");     
    -:    8:  else           
    2:    9:    if (argc%2==1)
    1:   10:      printf("et lige antal argumenter\n");   
    -:   11:    else 
    1:   12:      printf("et ulige antal argumenter\n");    
    -:   13:
    3:   14:  if (argc&lt;=3)
    3:   15:    printf("Højst to argumenter\n");   
    -:   16:  else 
#####:   17:    printf("Mere end to argumenter\n");    
    -:   18:  
    3:   19:  return 0;              
    -:   20:}  

Nu er det kun linie 17 som ikke udført endnu. Det er vigtigt at forstå at den resulterende kode-dækning er en sum af alle gennemløb af koden. Vil man slette historikken så skal "v2.gcda" filen slettes (har man mange C/C++ filer skal alle .gcda filer sletttes).

Jeg har rigtig mange test-gennemløb af min "rigtige kode" og har haft glæde af at se mønstre i koden som ikke eksekveres - netop med de hash-tegn foran de enkelte linier i ".gcov" filerne. Man kan udvide "gcov" kaldet med f.eks. "gcov -b", hvor man ydermere får udvidet fokus på alle branches (især if-else konstruktionerne). En anden rar udvidelse er at anvende programmet "ggcov", som læser output-filerne af "gcov" og præsenterer dette (lidt) grafisk. Et par eksempler kan findes her.

Faren i det her er nemt vises ved at slette "v2.gcda" og lave tre gennemløb.

$ v2 > /dev/null $ v2 1 > /dev/null $ v2 a b c d > /dev/null

Og igen køres gcov:

$ gcov v2.c File 'v2.c' Lines executed:100.00% of 10 v2.c:creating 'v2.c.gcov'

Jubi - alt er udført.... NEJ! Alle kombinationer er ikke udført - men alle linier er mindst udført én gang. Derfor er dette ikke en mirakelkur - men nærmere et værktøj, der kan give nogen hjælp, især med massivt gennemløb af koden.

Er der nogen af jer som anvender dette og har andre tips?

/pto

Send Tweet
Udskriv
Billede af Peter ToftOm Peter Toft

Peter Toft er senior specialist hos Renesas Mobile og har blogget om open source og Linux siden Version2's begyndelse. Blogger også jævnligt om andre sjove teknologi-områder.

Follow @petertoft

Kommentarer (3)

Opret en konto eller log ind for at følge indhold på Version2 - og bliv opdateret via e-mail eller rss

Følg kommentarer
Poul-Henning Kamps billede
Poul-Henning Kamp 31. dec. 2008 - 02.47
 
Brug det!

Jeg bruger gcov ret konsekvent.

Jeg tror nok jeg skrev om det i DKUUG-nyt første gang i 1988 eller noget i den stil, dengang post-processede jeg selv C-compilerens assembler output for at indsætte de nødvendige tællere.

Ideen fik jeg vist nok fra en Bell Labs Journal artikel.

pt. har jeg 81.94% dækning af Varnish kildeteksten fra mine automatiske test-cases.

Det er generelt svært at nå højere end ca. 80-90% uden at spilde en masse tid på at trigge fejlbetingelser eller provokere asserts.

Poul-Henning

  • Stem op 0
  • Stem ned 0
  • Log ind eller opret en konto for at skrive kommentarer
Peter Tofts billede
Peter Toft 31. dec. 2008 - 10.09
 
Re: Brug det!

Man får ikke fuld coverage - klart. Jeg har også en del linier kode til at håndtere mere eller mindre sygelige fejl - som jeg pt. ikke har set. Men PHK, hvad bruger du gcov til - at se steder i koden, der bruges mest - eller netop kode-dele, der ikke bruges?

  • Stem op 0
  • Stem ned 0
  • Log ind eller opret en konto for at skrive kommentarer
Poul-Henning Kamps billede
Poul-Henning Kamp 31. dec. 2008 - 11.43
 
Re: Brug det!

Det er faktisk svært at svare på Peter, for spørgsmålet er lige så meningsløst som "hvad bruger du en skruetrækker til ?"

For mig er gcov et universalværktøj der fortæller mig hvad min kode foretager sig.

F.eks kan man se om de automatiske test-cases kommer ordentligt ud i hjørnerne, eller sikrer sig at en bestemt test-case faktisk tester det man forventer.

Man kan også køre en reproduceret bug igennem og se hvilken vej den kom.

Specielt hvis det er en fejl der tager lidt tid at provokere, så er kode der kun er exekveret
en enkelt gang er et godt sted at stirre mistroisk.

Så er der "hvor tit sker det her egentlig ?" analyser.

Hvor tit læses en HTTP request i et read(2) kald og hvor tit skal der mere end et kald til ? Ville det hjælpe
at have en større buffer ?

Hvis et bestemt kodepath vælges en gang ud af 10 mio gør det måske ikke noget hvis det er lidt kluntet, bruges det
en ud af tusinde gange, bør det optimeres.

Man kan naturligvis selv indsætte tællere i koden for at besvare den slags spørgsmål, men det er nemmere at bruge gcov og få tællere "overalt".

Der er også den mere målsøgende performance vurdering.

Er lister sorteret på det rigtige kriterie ? burde de være hashes eller træer istedet ? Bør en funktion skilles i 99.99% tilfældet og undtagelserne flyttes til en anden funktion ? osv.

Men jeg kunne godt savne en komplementær facilitet til gcov, der istedet for at tælle alle basic blocks, istedet skrev i en cirkulær buffer hvor den har været.

Mange coredumps ville være nemmere at gennemskue hvis man kunne få at vide hvad CPUen (thread'en) har lavet de sidste par milli- eller blot micro-sekunder.

Jeg kunne også godt ønske mig lidt bedre presentation af resultatet, jeg hack'er selv output om til HTML:

http://phk.freebsd.dk/misc/cache_fetch.c.html

Men det kan helt sikkert gøres bedre af folk med mere forstand på den slags...

Poul-Henning

  • Stem op 0
  • Stem ned 0
  • Log ind eller opret en konto for at skrive kommentarer

Tilføj kommentar

Opret en konto eller log ind for at følge indhold på Version2 - og bliv opdateret via e-mail eller rss

Følg kommentarer
Log ind herunder eller opret en bruger for at skrive kommentarer
Du kan logge ind med din e-mail-adresse
Der er forskel på store og små bogstaver i adgangskoden.
Glemt adgangskode?

Seneste nyt

Microsoft-dansker gør C#-udviklere klogere med nyt kodeværktøj

Udgivet 23. maj 16.03Opdateret 24. maj 16.08

Rygte: Microsoft lancerer Office til iOS i november

Udgivet 24. maj 15.33Opdateret 24. maj 15.33

Yahoos nye browser får uheldig start - lækker eget sikkerhedscertifikat

Udgivet 24. maj 14.52Opdateret 24. maj 14.53

Danske internetudbydere nægter at blokere 12 pokersites

Udgivet 24. maj 13.58Opdateret 24. maj 13.58

Dokumentation: Her er Spillemyndighedens krav - og 12 ulovlige pokersider

Udgivet 24. maj 13.58Opdateret 24. maj 15.49

Flere it-nyheder »

Tilmeld dig Version2's it-nyhedsbrev og vind den nye iPad.

Seneste debat

  1. Danske internetudbydere nægter at blokere 12 pokersites

    5 comments.
    Last update 5 minutter 10 sekunder
    Skrevet af Johan S. Larsen
  2. Dokumentation: Her er Spillemyndighedens krav - og 12 ulovlige pokersider

    4 comments.
    Last update 5 minutter 19 sekunder
    Skrevet af Mikkel Kirkgaard Nielsen
  3. Meego-afløseren Tizen klar til at tage kampen op med Android

    12 comments.
    Last update 1 time 2 minutter
    Skrevet af Jacob Sparre Andersen
  4. Kynisk it-guru: »Internettet er basalt set noget lort«

    7 comments.
    Last update 1 time 9 minutter
    Skrevet af Poul-Henning Kamp
  5. Oracle tabte, vandt Google Java ?

    16 comments.
    Last update 1 time 19 minutter
    Skrevet af Poul-Henning Kamp
  6. Yahoos nye browser får uheldig start - lækker eget sikkerhedscertifikat

    1 comment.
    Last update 1 time 29 minutter
    Skrevet af Thue Kristensen
  7. GOTO - programming with the stars (F#)

    9 comments.
    Last update 1 time 39 minutter
    Skrevet af Baldur Norddahl
  8. ESA arbejder på interplanetarisk internet

    5 comments.
    Last update 1 time 43 minutter
    Skrevet af Jarle Knudsen

Mere debat »

It-virksomheder

Ciklum
|
Sharkcell
|
Intelliglobe
|
Clockwork Consulting ApS
|
ITX
|
BusinessMann
|
CODEWIRE.NET
|
Futurecom Business Solutions
|
Structura - IT
|
Bownty ApS
|
Relation House
|
Data-Force
 

Information

  • Kontakt redaktionen
  • Job- og annoncesalg
  • Teknisk support
  • Om Version2
  • Brugerbetingelser
  • Privatlivspolitik

Aktuelle emner

  • Agil udvikling
  • Android
  • Bruttolønsordning
  • Business Intelligence
  • Cloud computing
  • Download Windows 8
  • HTML5
  • Harddisk-priser
  • IE9
  • Intranet
  • It-sikkerhed
  • Kindle Fire
  • Multimedieskat
  • NemID
  • OS X Mountain Lion
  • Open source CMS
  • Projektledelse
  • Scrum
  • Sharepoint intranet
  • Storage
  • Ubuntu 11.10
  • Virtualisering
  • Windows 8
  • Windows Phone 7
  • iOS 5
  • iPhone 4S

Tjenester

  • Android-app
  • iPhone-app
  • RSS-feeds
Følg @version2dk
Tilmeld dig Version2's it-nyhedsbrev og vind den nye iPad.

Version2 udgives af

  • Mediehuset Ingeniøren A/S work Skelbækgade 4 1717 København V
  • Tlf. work 33265300