Valgrind, Coverity og FlexeLint

Når man som jeg skriver det meste af sin kode i C, så lærer man at værdsætte programmer der kan hjælpe med at spotte problemer.

De tre programmer i overskriften har hver sin taktik og og tilsammen gør de livet surt, selv for den mest kreative bug.

Valgrind kører programmet i en sandkasse som kan instrumenteres med forskellige "checkers". Den mest brugte er memcheck, der holder øje med alle referencer til memory. Valgrind er Open Source.

Coverity foretager en statisk analyse af programmet, udleder af koden hvilke mulige værdier variabler kan have og ser efter steder hvor det kunne give problemer. Coverity er købeware og prisen afhænger af hvor stor en kodebase man har. 500.000 linier koster $50.000 om året.

FlexeLint kigger på kildeteksten, som sådan, og kigger efter ting der tyder på problemer. Derudover foretager den en letvægts statisk analyse der ikke er ligeså raffineret som Coverity. FlexeLint koster $1000 for en enbrugerslicens.

Valgrinds styrke er, at det kigger på programmet mens det kører, derved bliver parametre, inputdata og andre dynamiske forhold taget i betragtning. Derudover er Valgrind+memcheck fantastisk til at finde "heisenbugs" ved at opdage at programmet bruger indholdet af ikke initialiseret hukommelse.

Coveritys styrke er at det ikke afhænger af parametrene, men istedet kigger på hvordan programmet reagerer for vilkårlige stimuli. Coverity kan udbygges med "modelkode" der gør et APIs garantier synlige for Coverity således at implementeringen ikke tages med i betragtning.

FlexeLints styrke er at det fanger fejl som de andre to tro er tastet ind med vilje: indrykningsfejl, lille 'L' istedet for ettal, while(0), signed/unsigned, returværdier der ignoreres nogle steder, dynamisk hukommelse der glemmes og meget mere.

Valgrind er en open source, gratis og nemt at bruge, så det er der ingen undskyldning.

Coverity har en temmelig grim prisliste. Heldigvis har de en fornuftig politik mht. open source projekter, men der er noget arbejde i at sætte det op og holde det kørende. Med mindre man har meget kode, er det nok ikke besværet og pengene værd. Hvis man har, er prisen utrolig fornuftig.

FlexeLint er noget af det eneste software jeg nogensinde har købt af egen fri vilje og jeg kan varmt anbefale det. Det tager lidt tid at få besluttet hvilke ting man vil og ikke vil advares om, per default er FlexeLint meget pernittengrynet, men de tusind dollars er snart tjent hjem i sparet tid.

Og hvis man er arrogant nok til at tro, at man ikke har brug for nogen af de tre værktøjer, så er "Bug Of The Month" fra FlexeLints forfatter en god måde at komme ned på jorden igen.

phk

Kommentarer (23)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
Torben Mogensen Blogger

De nævnte værktøjer til at finde bugs i C-programmer har karakter af at sætte en spand under et hul i taget i stedet for at lappe det.

Hullet i taget er C's mildest talt usikre lagermodel, som giver masser af muligheder for vand at komme ind. Hvis man er heldig, så regner det ikke, eller hullet er lige over badekarret, så der ikke sker noget ved, at det drypper lidt. Men hvis man er uheldig, så er hullet lige over sikringsboksen, og endvidere har det slet ikke regnet inden man får leveret produktet fra leverandøren, så man opdager først problemet næste gang, det regner.

Så brug dog et sprog, der har indbygget statiske og dynamiske checks og invarianter, der sikrer mod den slags fejl. Så behøver du ikke bruge den slags værktøjer. Hvornår havde du sidst en ikke-initialiseret variabel eller bufferoverløb i et ML-program? Hvornår fulgte du sidst en null-pointer eller tilgik for tidligt frigivet lager i et ML-program?

C har sin berettigelse nogle steder -- til programmering af meget små indlejrede systemer og til programmerings operativsystemkerner (og selv her findes der bedre alternativer) -- men C bliver brugt til meget andet, hvor det slet ikke hører hjemme. Det giver ikke mening at programmere økonomisystemer, web-browsere, oversættere eller simulationer i C.

  • 0
  • 0
Poul-Henning Kamp Blogger

Du er godt nok kommet højt til hest Torben :-)

Ja, C er ikke et "seler & livrem" sprog men du glemmer, meget belejliget for dit argument, at alle de "meget bedre" sprog er implementeret i C og kører under operativsystemer der er skrevet i C.

Forresten vil jeg da mægtig gerne høre hvilket sprog der er bedre end C til kerneprorgrammering og ikke mindst hvilke data du har der underbygger den, mildste talt, noget skråsikre påstand.

Poul-Henning

  • 0
  • 0
Jacob Sparre Andersen

Mig bekendt er Ada ikke ligefrem uegnet til kerneprogrammering. Har C i øvrigt fået »machine code insertions« med i standarden efterhånden?

Men hvis jeg skulle konkurrere med PHK i kerneprogrammering, så er jeg bange for at lige meget hvor godt et sprog jeg bruger, så vil det ikke være nok til at kompensere for PHK's erfaring og dygtighed på området.

Hvad angår implementation af andre sprog, så den ada-oversætter jeg normalt bruger hovedsageligt skrevet i Ada. Kodegeneratoren mener jeg dog er genbrug og skrevet i C.

Jacob

  • 0
  • 0
Peter Juhl Christiansen

Et udemærket indlæg, med relevant konkrete tips..opfordring til at skrive om sit eget ynglings værktøj til C programering.

Men altså KUN en C diskution.

At Torbens "Spand under hullet" diskution OGSÅ er ret interesant, er så en anden diskution, som jeg håber PH eller en anden tager op et andet sted.

Mener nemlig også at software industien er alt for koncervativ i valg af sprog, og vi skal være bedre til at bruge forskellige sprog, når det betaler sig.

Ville gerne bidrage med tips til C programering, men det er (synes jeg selv) heldigvis lang tid siden jeg har kodet i C.

  • 0
  • 0
Poul-Henning Kamp Blogger

Det er to relevante emner, helt sikkert. Grunden til at jeg disser Torben er at hans holdning ikke holder i praksis. Det er den slags høje datalogiske kæpheste der holder dataloger uden for relevans her i landet.

Jeg er helt enig med dig i at vi er for konservative om vores sprog. Taget i betragtning hvor let det faktisk er at skrive en compiler der spytter C kode ud som mellemsprog, så burde vi behandlve vores sprog som værktøjer og rette dem til og udvidde dem så de holdes ajour.

Rent faktisk har jeg i nogle år gået og pusslet med om man kunne bygge en overbygning til C til kerne og systemprogrammering.

Ideen er at beholde alle de egenskaber der gør C så velegent til denne type opgaver, men at opdatere det med "moderne" koncepter som linked lists, bitmaps og andet syntaktisk sukker.

Den anden siden af ideen er at lave en compiler der faktisk kan hjælpe med debugging, f.eks:

En compiler option der giver alle strukturer et "magisk" element med en tilhørende magisk værdi. Hver gang en pointer cast'es til denne struktur indsætter compileren kode der checker at det magiske felt har den rette thaumatologiske værdi.

En compiler option der indsætter kode der holder øje med kritiske pointerværdier (0xdeadc0de, 0xdeadbeef osv), således at pointer-tango detekteres hurtigst muligt.

Osv.

Men som min gode ven og lusepuster MrATA siger: "So much code to hack, so little time".

Poul-Henning

  • 0
  • 0
Torben Mogensen Blogger

Du skriver, at de "meget bedre sprog" jeg nævner er implementeret i C, og kører på OS'er skrevet i C.

De fleste funktionelle sprog har oversættere, der er imlementeret i samme sprog, som de oversætter. De flest SML-oversættere er således implementeret i SML og de fleste Haskell-oversættere er implementeret i Haskell. Mange af dem oversætter direkte til maskinkode, så C er slet ikke indblandet. her er du altså helt galt i byen.

Hvad angår operativsystemer, så indrømmer jeg, at de fleste mainstream operativsystemer på nuværende tidspunkt er skrevet i en blanding af C og assembler, men det anfægtede jeg heller ikke. De gængse mainstream operativsystemer er jo også mindst 20 år gamle (eller videreudviklinger af sådanne), så det er ikke overraskende, at de bygger på forældet softwareteknologi. Der er jo også mange systemer, der stadig bruger Cobol.

Det er absolut muligt at skrive operativsystemer og andet basisprogrammel i sprog som ML, Haskell, Clean eller Erlang, se f.eks.

http://homepages.inf.ed.ac.uk/wadler/realworld/erlang.html
http://homepages.inf.ed.ac.uk/wadler/realworld/linspire.html
http://programatica.cs.pdx.edu/House/
http://www.cs.cmu.edu/~fox/
http://citeseer.ist.psu.edu/669829.html
http://www2.ics.hawaii.edu/~esb/prof/proj/hello/
http://web.cecs.pdx.edu/~rebekah/papers/icfp05_h.pdf

Nogle af ovennævnte systemer er eksperimentelle, men det var Linux jo også i starten.

Der er også lavet systemprogrammeringssprog, der ligner C, men er sikret mod de fleste af de typiske usikkerheder fra C såsom bufferoverflow, for tidlig deallokering, følgning af null-pointere, osv. Disse sprog tager ofte mange elementer far funktionssprog. Se f.eks. Cyclone:

http://www.cs.umd.edu/~mwh/papers/cyclone-cuj.pdf

  • 0
  • 0
Poul-Henning Kamp Blogger

Det er da godt at de akademiske papers tårner sig op, men problemet er bare at de 80% af et operativsystem der skal til før man kan skrive et paper kun tager 20% af tiden og kun ville tage 20% længere hvis man skrev det i COBOL.

Problemet i et operativsystem er når man når til de sidste 20%, dem der tager 80% af tiden og som kræver omhyggelig koordination af software, hardware, interrupts for at operativsystemer får en performance og funktionalitet der fjerner det fra sandkasse klassen.

I en ende af branchen er det utroligt sjældent at finde akademiske papers der har relevans.

Så ja, i teorien kan man skrive i operativsystemer i hvadsomhelst, men i praksis kan man ikke.

Derfor er det vigtigt at have værktøjer der hjælper med at finde fejl i den "portable assembler" som C sproget nu en gang er.

Poul-Henning

  • 0
  • 0
Palle Simonsen

...den menneskelige faktor.

Nu har jeg været så længe i branchen, at jeg har haft fornøjelsen af at samarbejde med programmører der brugte alt lige fra Prolog og diverse Lisp til diverse Pascal, assembler, C, C++, Java og sågar VB og RPG m.m.m.

I min ringe erfaring er antallet af skjulte og knap så skjulte fejl ligefrem propertionalt med programmørens talent og erfaring og knap så meget med sprogets og afviklings miljøets frihedsgrader eller mangel på samme - selv en dygtig programmør kan lave få men interessante fejl i et 'sandkasse' sprog medens en talentløs programmør kan slå sig igennem selv de bedste beskyttelsesmekanismer.

  • 0
  • 0
Anders Reinhardt Hansen

Noget der slår mig ved hele den her diskussion er at folk råber fra hver sin ø.
Statisk verifikation af kode er en super god idé og overhovedet ikke begrænset til C-kode. Meget af den forskning der sker på området for tiden sker faktisk inden for ml og haskell. Problemet med c er og det er nok det Torben prøver at sige; det er et imperativt sprog og har operationer har derfor sideeffekter. Det gør det meget svært, og faktisk umuligt at bevise noget som helst om et stykke kode af en vis størrelsen.
Personligt har jeg det bare sådan med funktionelle sprog; at de er sjove at skrive i men umulige at læse. Hvis jeg skal læse andres kode eller min egen 3 måneder efter er det nærmest umuligt at forstå hele dybden. Dette gør sig til dels også gældende for C i mit tilfælde hvorimod Java og C# er betydeligt nemmere at læse.

Jeg ville personligt gerne se rigtig meget mere Java og C# kode i GNU/Linux, ikke i kernen men som nogle af de rigtig mange programmer der ikke arbejder direkte på kerne niveau.

Desværre virker det som om mange i OpenSource verdenen ser lidt ned på objekt-orienterede sprog.

  • 0
  • 0
Carsten Frigaard

> Hullet i taget er C's mildest talt usikre lagermodel, som giver masser af muligheder for vand at komme ind. Hvis man er heldig, så regner det ikke, eller hullet er lige over badekarret, så der ikke sker noget ved, at det...

Ja, akademisk set, men det er ret KISS at skrive C kode, og så checke det med en memory profiler ala valgrind. Så er den potte ude uden det helt store opbud af store melodramatiske forklaringer af "rigtige-metoder". Man skal huske på at det bedste jo er det godes fjende og C har vist sig særdeles god, robust og simpel.

Alternative sprog som Java og C# lægger seriøse hindringer i vejen for en kerne-programmør; f.eks. kan jeg nævne op imod ni forskellige allokeringsteknikker i C++ mod C#'s ene (se http://frigaard.homelinux.org/pub/the_toll_of_garbage_collection.pdf). Og nullpointer problemer er stadigt et hyppigt forekommende problem i f.eks. C#. Så den gode programmør må foretrække valgfriheden.

Husk også på at C eller C++'s stackallokering er yderst effektiv, en faktor 10 til 100 gange hurtigere (sådan i grove træk) end C# allokering (se igen http://frigaard.homelinux.org/pub/the_toll_of_garbage_collection.pdf).

Personligt benytter jeg mig af kodegenererede checks for cast's (hvis jeg overhovedet skal bruge sådanne), men jeg så da gerne at C eller C++ understøttede pre- og postconditions, men det er jo ikke være end at man allesteder kan indsætte programmeringsverdens vigtigste kommando: assert( ... ) !!!

Carsten

  • 0
  • 0
Claus Dræby

Jeg vil da lige nævne at vi med stort held benytter Valgrind på det embeddede projekt jeg sidder på i øjeblikket.

Det er relativt højniveau, med C++ abstraktioner for alt fra hardware til GUI elementer, og valgrind har bare været uvurderlig til at finde tvilvsomme omgange med memoryen.

Til sprogdebatten kan jeg bare tilslutte mig synspunktet: Gode programmer skrives af gode programmører i et hvilket som helst sprog.

Muligheden for at skrive et godt program er et lille underrum i en verden af forfærdelige programmer, uanset sprog.

  • 0
  • 0
Kim Højgaard-hansen

Symbian kan nævnes som et operativsystem der er skrevet i !C. Det er (så vidt jeg ved i hvert fald) skrevet helt i C++, desværre vist med nogle hacks her og der fordi de manglede ting der ikke var med i C++ standarden. De virker i hvert fald ganske fortræffeligt på de mobiltlf. vi sidder og koder på :)

  • 0
  • 0
Claus Stovgaard

1) kode checker værktøj er geniale. Jack Ganssle som jeg er lidt en fan af, anbefaler bl.a. http://www.splint.org/ som lint værktøj. Et andet super værktøjer er self kode sessioner, blandt programmørerne. Man mødes og gennemlæse modulerne, og kontrollere om de overholder standarden, samt udfører det job de skal. Hvis andre skal gennemlæse koden til en session, bliver kommentarerne generelt bedre, og der bliver gjort mere umage med variabelnavne osv.
2) Hvad sprog angår, så benyt da det som passer til opgaven. Jeg har lige arbejdet i 6 måneder på firmwaren til et APC ups system. Det var ca. 100.000 linjer C-kode (En MISRA afart). Undervejs skrev jeg også Java, til noget debug værktøj. Det næste projekt jeg skal i gang med fra september indbefatter det hele skrevet i C++, med den objektorienteret tankegang. Valg af sprog er for mig et spørgsmål om opgaven.

  • 0
  • 0
Peter Toft

Jeg orker heller ikke diskussionen om Haskel er bedre en C# eller høstblomst-- version 2.3 er endnu bedre....

Men for C/C++ debugging, så er valgrind god. Valkyrie er en grafisk overbygning som kan anbefales. Det gør det ofte nemmere at arbejde med - især for folk som ikke anvender valgrind i dagligdagen.

Valkyrie+Valgrind er "give and take" ca lige så god/dårlig som Purify.

Hvis man har C-kode
>>>>>>>>>>>>>><
int a[5],b[5],c[5],i;

i=-1;
b[i] = 7;
<<<<<<<<<<<<<<<
så fanges den ikke altid. Det kan være at beregningen af "i" skal laves lidt mere kompleks, men så fanges den slags fejl ikke af Purify.

PurifyPlus sutter totalt til C-kode sidste gang jeg så på det. Basale fejl går lige igennem.

Hvis man accepterer at kode godt må omskrives før det compiles, så er Insure++ god. Den fanger et par procent flere fejl end de øvrige, men er 100x sløvere end native C.

Purify: http://www-306.ibm.com/software/awdtools/purify/
PurifyPlus:
http://www-306.ibm.com/software/awdtools/purifyplus/
Valkyrie:
http://www.open-works.co.uk/projects/valkyrie.html
Valgrind:
http://valgrind.org/
Insure++
http://www.parasoft.com/jsp/products/home.jsp?product=Insure

  • 0
  • 0
Carsten Frigaard

> Men for C/C++ debugging, så er valgrind god. Valkyrie er en grafisk overbygning som kan anbefales.

...Eller bare brug "kcachegrind" til at analyser valgrind outputtet.

Jeg har leget lidt med "callgrind" modulet til valgrind - der given en code runtime performance analyse. Så valgrind levere egetlig det samme som dyre produktsuiter fra Rational eller Compuware. NuMega devpartner er også ca. ligeså svær at installere til Visual Studio, som det er at putte et operativsystem på en frisk computer - men måske er det blevet bedre i strømmen af nye versioner.

Men her skal man jo huske på, at man sådanne performance målinger påvirker hvad man måler og f.eks. giver

  • quantify (fra Rational)
  • samme type værktøj (fra Compuware, jeg har glemt navnet)
  • perf indbygget i tidligere versioner af VS
  • hånd timing (brug af clock() eller lign. timer)

alle forskellige resultater, ikke bare moderat forskellige men radikalt forskellige! Det bliver simpelthen svært at måle på små inlinede funktioner uden at måleprocessen har indflydelse f.eks. gennem nye cache mønstre. Måleprocessen i cpu tid er jo til at finde og trække fra, men kigger man på f.eks. Intels assempler instruktioner, ser man at pipelines og registerallokering er ret betydende for performance.

Så kan man nøjes med en grov analyse er brug af clock() (eller tilsvarende automatiske timer classe i C++, det tager 10 min. at skrive en sådanne) det bedste. Dog vil det tiltider være rart at trace tunge inline funktioner ned...men så kan man evt bruge et linietællingstool ala "cachegrind"

Mvh
Carsten

  • 0
  • 0
Anders Reinhardt Hansen

Den med at Java og C# er betydeligt langsommere end C er en gang fis. Det kommer an på anvendelses området. Numerisk performance i java især er til tider hurtigere end i C se selv:
http://www.itu.dk/people/sestoft/smp2/csharpspeed.pdf

Jeg har aldrig sagt at kernen i linux skal kodes i java, men det ville bringe flere udviklere til linux hvis mere opensource software var lavet i java.

  • 0
  • 0
Jørgen Henningsen

Flere opensource javaprojekter er da en god ide. Det er jo bare at komme igang.
Jeg tror grunden til manglen på opensource java projekter simpelten skyldes at de fleste hardcore kodere bruger 'C'.
Når jeg koder java, så savner jeg simpelthen frihederne i 'C'. Det er ligesom at køre motorcykel med støttehjul. Men jeg kan klart se fidusen i at kode java med platformsuafhængighed og massere af grafiske muligheder så god fornøjelse.

  • 0
  • 0
Henrik Kramshøj Blogger

Jeg vil tilslutte mig at der findes et væld af open source i Java. Specielt da jeg har fravalgt nogensinde at bruge PHP er det nødvendigt for mig at finde alternativer.

Det er blandt andet Apache Lenya, Apache Tomcat, OLAT (www.olat.org), Apache Ant.

Se evt. http://java-source.net/ for en bunke software der er open source og skrevet i Java

Jeg har en bunke Apache værktøjer, idet jeg så har en forventning om at de også eksisterer om 3 år ;-)

  • 0
  • 0
Morten Olsen

@anders,

Interessant artikel. Imponerende, især hvor tæt Java med sin begrænsninger i array-repræsentation og uden muligheder for at lave usikkert skullduggery kan komme så tæt på C. Som det gamle ordsprog sige, så kan grise godt komme til at flyve, givet tilstrækkeligt med motorkræft :)

Men Sestofte har ikke fået 100% af den mulige performance ud af sin C oversætter. Formodentligt er grunden til at MS CLR er hurtigere til divisionstesten at den bruger sse2 instruktioner istedet for de gamle 387 stak-baserede. På min pentium-m 1800 går tiden per iteration fra 24ns til 18ns hvis man oversætter med gcc -mtune=pentium-m -O3 -mfpmath=sse -mmmx -msse -msse2 -msse3, så C implementationen er igen hurtigst. Matrix multiplikationen kan sikkert også blive endnu hurtigere i C versionen med de parametre til gcc.

Ansvaret for Java's nogen gange lidt ufortjente ry som langsomt kan 100% lægges på de klap-hatte hos Sun der står bag den afskyelighed der er Swing.

Og for at komme lidt tilbage på sporet, så er det jo lidt synd for folk som PHK der bruger oceaner af tid på at pille i og tune virtual memory systemer, skønne spildte kræfter når folk så kører Java programmer med en garbage collector der kværner rundt i hele heapen i tide og utide. For slet ikke at snakke om hvordan shared-libraries og COW bliver gjort til skamme.

MS havde planlagt at bruge meget .NET til systemprogrammering i Vista, men kom i problemer, fordi det ikke er robust nok i low-memory situationer osv, tilsyneladende da det er gearet for meget til almindelig brugerprogrammering. Så C/C++ har bestemt stadigvæk sin berettigelse, især da til systemprogrammering.

  • 0
  • 0
Log ind eller Opret konto for at kommentere