Dette indlæg er alene udtryk for skribentens egen holdning.

Mange eller få fejl ?

29 kommentarer.  Hop til debatten
Blogindlæg14. januar kl. 15:43
errorÆldre end 30 dage

Som I sikkert er klar over, finder jeg det utroligt interessant hvad spørgsmålet er til Bruce Schneier's gamle spørgsmål "Er der mange eller få fejl ?"

Bruce's argument er, at hvis der er 100000 fejl i koden, batter det ikke noget at man fixer en af dem.

Omvendt, hvis der kun er 100, er én mindre bestemt værd at kæmpe for.

Fint nok, men hvordan finder vi så ud af om der er mange eller få fejl ?

Artiklen fortsætter efter annoncen

Som med det postulerede "mørke stof" i verdensrummet, må vi tage til takke med de indirekte vidnesbyrd der fra tid til anden dukker op.

Her er et Microsoft blog-post, om hvordan de har brugt c++20's nye consteval feature i deres egen compiler og fundet "~120" fejl kode der rapporterer fejl i kildeteksten.

Denne slags videnskabelige rådata er guld værd: Man indfører et check der aldrig tidligere har existeret og får på den måde en stort set un-bias'ed måling i et eller andet uberørt hjørne.

Desværre har de ikke skrevet hvor mange procent de 120 fejl udgør, så det har jeg sprugt dem om i en email.

Men vi ser om de svarer kan vi jo gætte.

Mit gæt er ca. 1.5%

phk

29 kommentarer.  Hop til debatten
Debatten
Log ind for at deltage i debatten.
settingsDebatindstillinger
29
19. januar kl. 11:46

I de fleste tilfælde ville jeg være udmærket tilfreds med nye releases, der blot reducerer mængden af fejl uden at tilføje nye features. Meget software lider af galloperende featuritis.

Langt det meste software der bliver skrevet ender ikke som ”standard” software med millioner af brugere. Langt det meste er software med få hundrede eller tusinde brugere hvor økonomien er tight og hvor første version helst kun indeholder det allermest basale. Der er måske kun et meget lille team der har bygget softwaren. Hvis man kun lige får første version ud uden at være i stand til at bygge videre så er det meget skidt. Det rammer produktiviteten kraftigt hos brugerne.

27
19. januar kl. 10:01

Jajo, hvis fejlen er at programmet ikke kan bruges. Hvis man ved hvordan programmet bliver kaldt og kan garantere, man ikke kommer ind i den fejlende branch/sekvens/kombination, kan det jo bruges

Men det er stadigvæk et problem. De gør koden mindre agil. De koster penge at opdage, at vurdere, etc. De gør det sværere at for nye programmører at sætte sig ind i koden. Etc. Men ja, der er forskel på hvor vigtige fejl er.

Ovenstående er ofte et udtryk for, at fejlretning nedprioriteres i forhold til at implementere nye features

Eller også er det manglende test, sjusk, etc. Der er mange grunde.

Men uanset hvad så gør det at det er nærmest umuligt at komme med realistiske vurderinger af hvornår et sådan projekt er færdigt. Læg så oveni at det ofte bliver svært at refactorere koden så længe det står på, det skaber en kultur af at man signer af på at features er implementeret men ikke fejlrettet, etc. etc. etc.

De fleste der laver software har prøvet at arbejde sådan. Features bliver færdige. Der er fremskridt i planen. Det går derudaf. Men når man så når til afslutningen så ender den med at tage mere tid end alt det foregående. Vigtigst: tid som man ikke har planlagt med og hvor man står i mørket når man skal vurdere hvor lang tid der er tilbage.

Typisk nedprioriteres fejl, der ikke er de mest vigtige, og de bliver ved at være der mange år, og rettes aldrig.

Og hvis man fortsætter sådan så ender fremtidige software releases typisk med at blive "små hop på stedet". Små udvidelser der ikke flytter det helt store. Måske er problemet blot i et enkelt område som ingen tør pille ved og hvor man så planlægger nye features omhyggeligt til ikke at pille ved netop det.

26
18. januar kl. 23:15

Men hvis et team bruger mere end 30-40% af tiden på at rette fejl der er mere end 3 måneder gamle så ved man at der er meget lang vej igen selv hvis alle features var kodet færdigt i morgen. Så indikerer det at kode kvaliteten er lav og at den ikke er ordentligt testet. Det er den slags projekter hvor det i praksis er umuligt at sige hvornår man er færdig.

Ovenstående er ofte et udtryk for, at fejlretning nedprioriteres i forhold til at implementere nye features. 60-70% af udviklerne arbejder med nye features, og at tilfører nye fejl. Fejlretningen gøres af 30%-40% og antallet af fejl vokser hurtigere, end fejlene udbedres. Typisk nedprioriteres fejl, der ikke er de mest vigtige, og de bliver ved at være der mange år, og rettes aldrig. Derimod øges listen af features uafbrudt. Rettes fejl, kommer de ofte tilbage senere, fordi at man kommer til at en bruge gammel kode igen.

Nogle virksomheder bruger 100% af resourcerne til at rette fejl, indtil de alle er fundet, og stopper med at udvikle nye, indtil der er styr på udviklingen og produktionen.

25
18. januar kl. 17:39

Først: Alle fejl er naturligvis et problem.

Jajo, hvis fejlen er at programmet ikke kan bruges. Hvis man ved hvordan programmet bliver kaldt og kan garantere, man ikke kommer ind i den fejlende branch/sekvens/kombination, kan det jo bruges. Hvem kender ikke tanken 'Ah det kunne du jo have sagt dig selv, programmet ikke var testet/forberedt til'? En fejls problem/alvorlighed er self set ud fra spec'en af hvordan programmet bruges.

24
17. januar kl. 22:59

Først: Alle fejl er naturligvis et problem.

Men der hvor man kan se om et projekt er i seriøse problemer er ved at se på hvor meget tid de bruger på at løse gamle fejl.

Hvis et team bruger 95% af fejlretningstiden på at rette fejl der er en uge gamle, så indikerer det blot at de har for travlt og at når de holder op med at putte features ind så falder bug count typisk hurtigt.

Men hvis et team bruger mere end 30-40% af tiden på at rette fejl der er mere end 3 måneder gamle så ved man at der er meget lang vej igen selv hvis alle features var kodet færdigt i morgen. Så indikerer det at kode kvaliteten er lav og at den ikke er ordentligt testet. Det er den slags projekter hvor det i praksis er umuligt at sige hvornår man er færdig.

23
17. januar kl. 22:43

Har man tre uafhængigt skrevede programmer

Nogen i den stil gjorde Airbus på dele af softwaren til A300. Programmerne var skrevet i to forskellige sprog og med to forskellige processortyper. Hvad man gør i dag ved jeg ikke.

22
17. januar kl. 22:36

Altså, man har tilføjet en mekanisme, som "fanger" hidtil oversete fejl i kildeteksten.

Jeg antager: der kun blev kigget på errormsg(...) funktionen?

Hvis man bruger enum errorno{C2000, C2001, ... C9999} ser der ud til at være ca 8000 muligheder; så 120x100/8000=1.5%.

Jeg havde først regnet med ca 10000 fejlkoder og var derfor nået til at procenten måtte være 1.2% (= 12000/10000).

Så jeg må (modvilligt) erklære mig enig med phk (som sikkert kan forklare sit resultat med et helt regnestykke;).

20
17. januar kl. 17:47

Er det 1.5% af alle eksisterende fejl, alle eksisterende kendte fejl, eller alle fejl inkl. historiske (fixede) ?

Det kunne være interessant at vide, hvis man introducerer en ny sprog-feature f.eks. "consteval" "const", elelr "private" og det finder fejl, hvormange fejl indikerer det så der er ikke er fanget? x10 ?

19
17. januar kl. 16:23

er et godt trick: bild "de studerende" ind, at du ikke kan finde en oplysning og ,,, har faktisk selv gjort det, før jeg vidste hvordan "de" ville reagere; jeg blev klogere af at læse afleveringerne. Om "de" forstod, skal jeg være usagt;-)

Men det sagde han i 1980, længe før google, så det er der jo ingen der nogensinde har hørt om :-/

(fra cs.Stanford.edu, nr 1 i google søgning)

Kilde:

Det er måske det oftest citerede af Tony Hoare; 1.3 mio på .58 s.

18
17. januar kl. 14:29

"Program testing can be used to show the presence of bugs, but never to show their absence!"

Edsger Dijkstra (1970) "Notes On Structured Programming" (EWD249), Section 3 ("On The Reliability of Mechanisms"), corollary at the end.

16
17. januar kl. 10:46

Tony Hoare sagde til sin Turing Award lecture

There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.

Min fornemmelse er, at langt det meste kommercielle software er i den sidste kategori.

Han sagde også

The real value of tests is not that they detect bugs in the code, but that they detect inadequacies in the methods, concentration, and skills of those who design and produce the code.

hvilket heller ikke lyder helt ved siden af.

15
17. januar kl. 10:37

Jeg så engang en metode til at estimere antallet af uopdagede fejl:

Sæt to hold til at lede efter fejl i et bestemt antal timer. X fejl bliver fundet af hold A, Y fejl bliver fundet af hold B, og Z fejl bliver fundet af begge hold. Ud fra en antagelse om, at sværheden af at finde fejl er normalfordelt (nogle få er nemme at finde, nogle få er meget svære at finde, men de fleste ligger midt imellem), kan man ud fra de tre tal estimere antallet af fejl, som ingen af de to hold har fundet. Groft sagt, jo flere fejl, der kun bliver fundet af af hold, jo flere uopdagede fejl er der. Jeg husker dog ikke formlen.

Der er nok ret stor usikkerhed i resultatet, men som et nulestimat fungerer det nok meget godt.

13
17. januar kl. 06:10

Hvad #11 beskriver er hvad store firmaer gjorde i "gamle dage" for 40-50 år siden; det kræver også at man har fx 3 velkvalificerede "lead-programmers" - eller nogle der "ligner".</p>
<p>I moderne tider kan man bruge 3 teams bedre fx ved at lade team 1 designe, team 2 udvikle test og team 3 skrive koden. Evt. rotere opgaverne mellen stints. Eller lade hvert team designe, skrive test og udvikle koden til testen kører fejlfrit.</p>
<p>Det er hurtigere at udvikle - fordi der går sport i det - så den "hellige" produktivitet forbedres væsentligt;) Går det hurtigere er der brug for færre programmører - eller dem man har når flere opgaver.

Ja, vi kan godt kalde hold for teams. Men, skal vi sikre os, at det fungerer, så kan vi bedst gøre det ved at have flere programmer, der virker identisk, og automatisk afgør, at de er ens, og fungerer.

Antages, f.eks. at der er hackere på de forskellige hold, der lægger en bagdør ind. Har de ingen kommunikation med hinanden, så er de ikke i stand til, at lægge samme bagdør ind i de forskellige koder. Det betyder, at de koder, der er uden den pågældende bagdør giver samme resultater og kører videre, mens den, eller de, der er hacket, kobles fra.

Man kan også køre i debug mode, hvor man altid vælger den kode der svarer forkert. Det er godt som "demo" kode, hvor man forventer hackere får adgang. De vil derved altid få den kode, som der er hacket. Og man kan se, hvad deres hensigt er. Men, naturligvis kan aldrig ske noget ved det, for koderne svarer ikke ens, og derfor effektualiseres det ikke andet end tilsyneladende.

Det er korrekt, at det ikke er den mest effektive måde at anvende programmørerne på, men man har en sikkerhed for at det er gjort korrekt, som man aldrig opnår, ved at have de samme til at kode det. Man kan også have f.eks. to teams - en der laver koden, og en anden der laver kontrol. Men, den mest effektive kontrol, er ofte at lave koden uafhængigt, og kontrolere identiteten.

Det, som så kan være et problem, er kaotiske sprog, hvor intet foregår ens fra gang til gang. Så vil der næsten altid vise sig fejl, før eller siden. Det er simpelthen umuligt, at gennemteste alle kombinationer, når det er kaos, og ingen måske reelt ved, hvad som foregår. Derfor, er et af de vigtigste designkrav 100% determinsme. Uden determinisme, så vil uoverskueligheden vokse til det uendelige, og det vil være umuligt at gøre korrekt. Det eneste positive der er ved kaos metoden, er at der ikke er skyggen af bevis.

12
17. januar kl. 03:46

Hvad #11 beskriver er hvad store firmaer gjorde i "gamle dage" for 40-50 år siden; det kræver også at man har fx 3 velkvalificerede "lead-programmers" - eller nogle der "ligner".

I moderne tider kan man bruge 3 teams bedre fx ved at lade team 1 designe, team 2 udvikle test og team 3 skrive koden. Evt. rotere opgaverne mellen stints. Eller lade hvert team designe, skrive test og udvikle koden til testen kører fejlfrit.

Det er hurtigere at udvikle - fordi der går sport i det - så den "hellige" produktivitet forbedres væsentligt;) Går det hurtigere er der brug for færre programmører - eller dem man har når flere opgaver.

11
17. januar kl. 01:42

Har engang i 90erne været udsat for 'Fagan Inspection' TM/R,.. -kursus af Michael Fagan himself. Vi klaskede lår, da han kom med sin salgstale og påståede vilde besparelser ved at bruge hans umiddelbart bekostelige inspektion process á 4 timer for 4 udviklere per 250 linier kode. Men piben fik en anden lyd. Det er skam dyrere at finde fejl efter man har afleveret producktet. Og der er sjældent lavet kode, der er helt fri for fejl. Det han så heldigvis påstod var, at man ikke behøvede knække budget-halsen og indføre det på al koden med det samme, men blot på den kode der identificeres som mest hyppigt brugt og/eller kritisk.

Jeg mener, at man burde overveje, at have flere hold, til at lave eksakt den samme kode, og lave specifikationerne, så funktionen kan sammenlignes, når koden udføres. Har man tre uafhængigt skrevede programmer efter samme specifikation, kan man evt. vælge en fra, hvis de to svarer ens. Det at bruge tre gange så lang tid, som udviklingsarbejdet tager, er ofte lidt, sammenlignet med det som spares, ved at vide implementeringen er uden fejl, og at man ved at sammenligne dem, får fejlene hurtigt. Hver hold, vil dertil skulle skrive test programmer, hvor man automatisk kan tjekke, at alle linjer og branches er testet, og når at man udsætter softwaren for de samlede tests, så er stor sandsynlighed for, at det viser sig, hvis der er fejl i en af programmerne. Flere hold der arbejder med samme kode uafhængigt, løser ofte problemerne på forskellige måde - nogle bedre end andre. Dette vil man ikke opnå ved et minimalt hold. Her er kun en løsning, og den er besluttet er korekt og bedst. Hvilket den normalt ikke er.

10
17. januar kl. 01:30

De færreste programmører interesserer sig for, om der er fejl - f.eks. i en specifikation. Tag eksempelvis C++ specifikationen - er der fejl i - og hvor mange? Lav en liste, over alle fejlene i C og C++. Men, hvad er så en fejl. Jeg plejer at sige, at enhver kode, der kan medføre ikke deterministisk opførsel, eller uønsket opførsel er en fejl (med mindre det er direkte specificeret, f.eks. med en tilfældigheds funktion). En liste over samtlige steder, hvor der kan gå galt i C++, er det de færreste programmører der gidder at bruge tid på at udarbejde, og så kan vi diskutere, hvorvidt de overhovedet har interesser i, at finde fejl. De fleste programmører, der får en specifikation, begynder at kode straks, og finder aldrig fejlene i specifikationen. Måske kan de ikke se de er der, for man gør jo, som der står man skal. Og man vurderer ikke, om det der står giver mening.

9
16. januar kl. 01:37

Jeg kom straks til at tænke på følgende passage fra fvwm's man page:

As of fvwm 0.99, there are exactly 39.342 unidentified bugs. Identified bugs have mostly been fixed, though. Since then 9.34 bugs have been fixed. Assuming that there are at least 10 unidentified bugs for every identified one, that leaves us with 39.342 - 9.32 + 10 * 9.34 = 123.402 unidentified bugs. If we follow this to its logical conclusion, we will have an infinite number of unidentified bugs before the number of bugs can start to diminish, at which point the program will be bug-free. Since this is a computer program, infinity = 3.4028e+38, if you don't insist on double-precision. At the current rate of bug-discovery, we should expect to achieve this point in 3.37e+27 years. I guess I better plan on passing this thing on to my children....

8
15. januar kl. 11:50

Folk der inspicerer koden er forskellige. Folk der laver koden er forskellige. Men det er usandsynligt der ikke bliver fundet fejl, sikkert de her 1 per 20-100 linjer, ja.

Har engang i 90erne været udsat for 'Fagan Inspection' TM/R,.. -kursus af Michael Fagan himself. Vi klaskede lår, da han kom med sin salgstale og påståede vilde besparelser ved at bruge hans umiddelbart bekostelige inspektion process á 4 timer for 4 udviklere per 250 linier kode. Men piben fik en anden lyd. Det er skam dyrere at finde fejl efter man har afleveret producktet. Og der er sjældent lavet kode, der er helt fri for fejl. Det han så heldigvis påstod var, at man ikke behøvede knække budget-halsen og indføre det på al koden med det samme, men blot på den kode der identificeres som mest hyppigt brugt og/eller kritisk.

7
15. januar kl. 08:09

Der er selvsagt mange interessante betragtninger i dette felt: Det ledelsesmæssige, udviklingsprocessen, klassifikationen, visualiseringen, gruppdynamik etc.

Men spørgsmålet stillet af PHK var relateret til antal af fejl i tidligere utestet (-ish) kode og det var det jeg prøvede at addressere. Som nævnt ca. 1 per 20-100 liniers eksekverbar kode i et helt konkret setup.

Er der andre der har tal at dele?

6
14. januar kl. 23:20

Jeg har med held brugt "cumulative bug arrival" pr. effektiv test tid, som et simpelt og effektivt værktøj for udviklings grupper på 10 til 100 mand.

For en givet udviklingsfase bør kurven være en S kurve, som flader ud når produktet når en vis modenhed. Kurven blev løbende opdateret og "hængt på væggen" så alle havde synlighed for dens udvikling. Som en ekstra sikkerhed når kurven havde fladet ud, var der en ekstra stopklods der krævede en uges effektiv test tid uden kritiske fejl, før man kunne gå videre til næste fase.

Kurven afslørede grupper af udviklere eller kode moduler der aldrig fladede tilstrækkeligt ud og hvor "en uge uden kritiske" fejl blev konstant skubbet. Det var et effektivt management værktøj til at identificere hvor lokkummet brændte. Og fordi kurverne var meget synlige for hver gruppe, greb de selv ind i forbedring af arkitekturer, processer og bemanding, og sjældent havde behov for overordnet management indgreb. Derudover gav kurvens form et godt bud på en realistisk tidsplan.

Vi valgte en kumulativ kurve, fordi den er "glattere", og derfor mere statistisk significant (støjfri). Og den er også selv-normaliserende: kurvens form bør være atlid være en S kurve, uafhængig af antal bugs, og derfor var den visuelt meget afslørende.

Det er meget vigtig at man ikke går i for stor detalje med defintion af alle tænkelige finurligheder. Så drukner man i metrikker, taber overblikket, og risikerer at det går op i hat og briller med overdokumentation. Og værst af alt, bliver vedligholdelse af bug kurven for besværlig og den opdateres ikke løbende. Det er vigtigere at måle hele tiden end at satse på at måle meget "præcist".

Dog kræves konsekvent brug af bug database med tilhørende ca. fem kategorier af bug severity og løbende opfølgning. For at lette udviklerne benyttede vi en fuldtids "bug hjælper" der vandrede mellem udviklingsgrupperne og hjalp med data indsamling, sikring af rimelig konsistens, og særdeles vigtigt, med at estimere effektiv test tid som er nødvendigt for at få en retvisende kurve. Vedkommende var en hjælper, ikke en "indpisker". Herved kunne vi lade "the law of large numbers" give os en pæn, menigsfuld og rimelig retvisende kurve.

Efter benyttelse af metoden i et par år var meldingen fra direktionen klar. Fejl raten var faldet så meget, både i intern testning og i klager fra sælgere og kunder, at man lidt spøgefuldt stillede sprøgsmålet, "Er udviklingsholdene presset hårdt nok til at skabe ny funktionalitet og innovation og bevare konkurrencedygtigheden?"

Og til sidst er jeg stadig fan af Fred Brooks "The Mythical Man-Month". Den indeholder mange sandheder som stadig har stor relevans idag.

5
14. januar kl. 20:26

Hvad regnes som fejl? Er det kun hvis routinen får et valid input of returnerer et fejlagtigt output? For mig dette er en alvorlig fejl, men hvad hvis input er fejlagtigt eller "out of range"?

  1. Returner det bedste resultat baseret på input data
  2. Returner et resultat som ikke er korrekt (F.eks. en 0 værdi).
  3. Returner en fejl, typisk en exception.

Generelt er 3) det bedste, men det vil normat gøre koden langsommere da der skal foretages flere checks.

Når jeg programmere har jeg ikke et standard svar, det varierer afhængig af situationen.

4
14. januar kl. 20:09

Meget interessant. Specielt ville det være spænde hvis du kunne uddybe hvorfor drømmen ikke blev til virkelighed: altså hvorfor fik I aldrig fulgt op? Og hvis det umiddelbare svar er af ledelsesmæssig karakter, så er jeg sikker på at du kan uddybe med dine egne tanker om hvorfor ledelsen ikke lod jer forfølge drømmen.

3
14. januar kl. 18:24

Generelt klassificerede vi fejl bredt, men der var tale om reelle fejl der ville kunne manifestere sig i forkert opførsel. Typisk corner cases. Meget sjældent, hvis overhovedet, katastrofale så som memory corruption eller processor exceptions.

Klassifikationen vi mest var interesseret i var af processorienteret art: i hvilken del af udviklingsprocessen blev fejlen introduceret: specifikation, design, development, integration, operation. Tanken var at holde dette op imod i hvilken del af processen fejlen blev fundet i. Her var unit test kun en del af spillet.

Drømmen var at kunne bruge den viden til at ændre udviklingsprocessen målrettet. Men vi fik ikke rigtig fulgt op på de data i det omfang man kunne.

2
14. januar kl. 17:11

@Morten: Hvad definerede I som fejl? eller måske spurgt på en anden måde. Havde i en eller anden slags kategorisering der fortalte noget om hvor mange fejl der var af lille betydning og hvor mange der var (potentielt) katstrofale?

1
14. januar kl. 16:46

Det bliver jo hurtigt lidt anekdotisk og urepræsentativt og det er også muligt at hukommelsen spiller mig et puds, men:

For kode som ikke havde unit tests, baseret på erfaring fra et firma der lavede satellittelefoner og modems, fra 2003 - 2007 (ca), fandt jeg at når vi testede systematisk var det nærmest sikkert at der blev fundet en fejl for hver 20 - 100 liniers eksekverbar kode.

Det kan jo hurtigt blive til en del for en mellemstor kodebase. Jeg aner ikke om vi var specielt gode eller dårlige, formentlig nogenlunde i midten for perioden.

Men det var næsten altid en øjenåbner, selv for de meget erfarne udviklere.