2.15

View in English

2.15 Felsökning och problemlösning

Översikt och motivation

Felsökning är det disciplinerade arbetet att ta reda på varför ett system gör något det inte borde, och problemlösning (troubleshooting) är samma färdighet vänd mot ett körande produktionssystem under tidspress. Båda är den vetenskapliga metoden tillämpad på defekter: du observerar ett överraskande beteende, formulerar en hypotes om dess orsak, utformar ett experiment som skulle bekräfta eller vederlägga den och låter belägget, inte din aning, tala om vad du ska ändra. Gjort på det här sättet är felsökning en lärbar, undervisningsbar teknisk färdighet. Gjort som folklore blir den vidskepelse: att ändra slumpmässiga rader, starta om servrar och hoppas.

För ett stort team är skillnaden dyr. En enda svår defekt kan dra in ingenjörer över flera tjänster, förbruka jourtimmar och stoppa en release. När varje person felsöker på instinkt växer inte den insatsen, eftersom ingen kan reproducera eller förklara vad någon annan prövade. När teamet delar en metod (reproducera först, isolera genom sökning, fånga felet i ett misslyckat test, åtgärda sedan) förvandlas samma insats till en upprepbar process och en växande regressionssvit. Felsökning hänger tätt ihop med teststrategi (kapitel 2.4), med programvarukvalitet (kapitel 2.11) och med de konstruktionsvanor (kapitel 2.9) som gör kod diagnostiserbar från första början.

I företags- och myndighetsmiljöer stiger insatserna. Företagsdefekter korsar tjänste- och teamgränser, så den som ser symptomet är sällan den som äger orsaken. Myndighetssystem lägger till begränsningar de flesta ingenjörer aldrig möter: luftgapade eller begränsade miljöer där du inte kan koppla en felsökare till produktion, reproducerbara byggen som måste diagnostiseras utifrån artefakter och revisionsspår som måste registrera vad du ändrade och varför. I alla tre är målet detsamma: ersätt gissning med belägg.

Nyckelprinciper

  • Reproducera innan du teoretiserar. En bugg du inte kan utlösa på begäran är ett rykte, inte en defekt.
  • Felsökning är hypotesprövning. Ange vad du tror och utforma sedan det billigaste experiment som skulle kunna bevisa att du har fel.
  • Läs felet och stackspåret först. Systemet talar vanligen om var det gick sönder innan du ändrar en rad.
  • Sök i problemrymden, skanna den inte. Halvera den misstänkta regionen varje steg i stället för att läsa uppifrån och ned.
  • Reducera till det minimala. Skala ned fallet tills bara den väsentliga utlösaren återstår.
  • En ändring i taget. Ändringar med hagelbössa förstör det belägg som skulle ha berättat vilken ändring som spelade roll.
  • Fånga felet i ett misslyckat test innan du åtgärdar det. Rättelsen är bara bevisad när det testet blir grönt och förblir grönt.
  • Hitta grundorsaken, inte det närmaste symptomet. En lapp som döljer symptomet lämnar defekten att återkomma.

Rekommendationer

Reproducera defekten pålitligt innan du ändrar något

Ditt första jobb är en pålitlig reproduktion: en uppsättning steg eller ett automatiskt fall som utlöser buggen på begäran. Utan den kan du inte skilja en verklig rättelse från en slump, eftersom symptomet kan komma och gå av skäl du aldrig kontrollerade. Fastställ indata, miljön, versionerna och tidpunkten. Om buggen är intermittent, jaga den dolda variabel som får den att visa sig (en särskild datapost, en klockgräns, en samtidig begäran) tills reproduktionen är pålitlig. En pålitlig reproduktion är den enskilt mest värdefulla artefakten i felsökning, eftersom allt efter den blir mätbart.

Läs felet, loggarna och stackspåret innan du rör koden

Innan du formulerar en enda teori, läs vad systemet redan sagt dig. Stackspåret (registret över anropskedjan i ögonblicket för felet) namnger vanligen filen, raden och sekvensen som fallerade. Undantagsmeddelandet, loggraderna runt det och värdena i omfattning avgränsar sökningen innan du har ändrat något. Ingenjörer slösar timmar på att teoretisera om orsaker som stackspåret uteslöt på rad ett. Behandla felutdata som det första vittnet, läs det noggrant och fullständigt och besluta först sedan vad du ska undersöka.

Isolera genom binärsökning av problemrymden

Skanna inte koden uppifrån och ned. Sök i den. Använd binärsökning: hitta en punkt där tillståndet fortfarande är gott och en punkt där det redan är dåligt, kontrollera sedan mittpunkten och upprepa, och halvera den misstänkta regionen varje gång. Det förvandlar en sökning på tusen rader till tio frågor. När regressionen dök upp över ett intervall av commits, tillämpa samma idé på historiken med bisektion: git bisect går igenom commitintervallet, och du markerar varje revision som god eller dålig tills den namnger den exakta ändring som introducerade defekten. Automatisera testet god-eller-dålig så kör bisektionen sig själv.

Reducera till ett minimalt reproducerbart exempel

När du kan utlösa buggen, krymp den. Ett minimalt reproducerbart exempel är den minsta indata och kodväg som fortfarande fallerar: ta bort data, funktioner och steg tills varje ytterligare borttagning gör att buggen försvinner. Reducering är inget onödigt arbete. Varje element du eliminerar är en orsak du har uteslutit, så det minimala fallet pekar ofta rakt på defekten. När indata är stor eller strukturerad, automatisera krympningen med delta-felsökning, en algoritm som systematiskt tar bort bitar av en misslyckad indata för att hitta den minimala misslyckade delmängden. En liten, självständig reproduktion är också den bästa tänkbara felrapporten att lämna till ett annat team.

Instrumentera med loggar och använd sedan en interaktiv felsökare

Anpassa verktyget efter buggen. Loggning och riktad instrumentering är bäst när du behöver se beteende över tid, över processer eller i en miljö du inte kan pausa. En interaktiv felsökare, som låter dig sätta brytpunkter, stega rad för rad och inspektera levande tillstånd, är bäst när du kan köra koden lokalt och behöver bevaka en enskild körning noga. Lägg till instrumentering som ett medvetet experiment knutet till en hypotes, inte som utspridda utskriftssatser, och ta bort den eller befordra den till permanent strukturerad loggning när buggen är löst. I produktion, lita på observerbarhetsdriven felsökning: högkardinalitetshändelser och distribuerad spårning (kapitel 9.2) låter dig följa en begäran över många tjänster, vilket ofta är det enda sättet att felsöka ett distribuerat system du inte kan koppla en felsökare till.

Skriv ett misslyckat test som fångar buggen innan du åtgärdar den

Innan du skriver rättelsen, skriv ett test som fallerar på grund av buggen. Det gör tre saker på en gång: det bevisar att du faktiskt förstår orsaken, det definierar exakt vad “åtgärdat” betyder och det blir ett permanent skydd. Gör sedan rättelsen och se testet bli grönt. Det testet ansluter nu till din svit som ett regressionstest-skydd, så att samma defekt inte kan återvända obemärkt. Den här praxisen knyter felsökning direkt till din teststrategi (kapitel 2.4): varje svår bugg du löser lämnar sviten starkare än den fann den, och ett opålitligt test får samma behandling (reproducera icke-determinismen, skydda sedan mot den) snarare än en omförsöksannotering.

Hitta grundorsaken och håll analysen skuldfri

Att åtgärda symptomet är inte att åtgärda buggen. Spåra felet tillbaka till dess verkliga ursprung och fråga varför på varje lager tills du når en orsak du kan ta bort snarare än maskera. För defekter som nådde produktion, kör en skuldfri grundorsaksanalys som en del av incidenthanteringen (kapitel 9.3): fokusera på de system- och processvillkor som lät buggen levereras och överleva, aldrig på individen som skrev raden. Skuldbeläggning driver information under jorden, och felsökning drivs av information. Resultatet är både en rättelse och en ändring i hur den klassen av defekt fångas tidigare nästa gång.

Avvägningar: för- och nackdelar

TillvägagångssättFördelarNackdelar
Loggning och instrumenteringFungerar i produktion och distribuerade system. Fångar beteende över tidBrus, kostnad och loggspridning. Kan störa tidsbuggar
Interaktiv felsökarePrecis, levande tillståndsinspektion. Snabb för lokala buggarVärdelös i begränsad eller luftgapad produktion. Kan dölja samtidighetsbuggar
Reproducera-först-disciplinFörvandlar gissning till mätning. Möjliggör ett misslyckat testLångsam i förväg. Vissa buggar är genuint svåra att utlösa
Binärsökning och bisektionSnabb isolering, även i obekant kodBehöver ett pålitligt test god-eller-dålig. Svårt när buggar samverkar
Reducering med delta-felsökningKrymper enorma indata automatiskt till utlösarenUppsättningskostnad. Förutsätter att felet är deterministiskt
Åtgärda symptomet nuÅterställer tjänsten snabbt under pressLämnar grundorsaken att återkomma. Ackumulerar skuld

Den centrala spänningen är hastighet mot säkerhet. Under en produktionsincident kan du behöva stoppa blödningen först (en återställning eller en symptomlapp) för att återställa tjänsten, och det är legitimt. Misstaget är att stanna där. Lös spänningen genom att skilja de två jobben åt: begränsa snabbt för att skydda användare, reproducera sedan, hitta grundorsaken och lägg till regressionsskyddet innan du betraktar defekten som stängd. En symptomrättelse utan uppföljning är en bugg du har gått med på att möta igen.

Frågor att diskutera med ditt team

  1. När någon träffar på en svår bugg, vad är det första hen gör, och är det att reproducera eller gissa? Det ärliga svaret avslöjar om ert team har en gemensam metod eller ett rum fullt av privat folklore. Be människor berätta högt om sin senaste svåra defekt: fick de en pålitlig reproduktion först, eller började de ändra kod och starta om saker? Ett team som reproducerar först kan lämna en bugg mellan människor, eftersom reproduktionen följer med. Ett team som gissar kan inte, eftersom varje försök är orepeterbart. Det här spelar större roll när teamet växer, eftersom personen som ser ett symptom alltmer inte är personen som kan åtgärda det. Om standardvalet är gissning, kom överens om reproducera-först som en norm och gör en ren reproduktion till inträdesavgiften för ett buggärende.

  2. Kommer de buggar vi åtgärdar tillbaka, och skulle vi veta om de gjorde det? En defekt som återvänder är en defekt vars grundorsak aldrig togs bort och vars rättelse aldrig skyddades av ett test. Hämta förra kvartalets incidenter och återöppnade ärenden och räkna hur många som var upprepningar eller nära kusiner till tidigare buggar. Varje upprepning är belägg för att teamet lappade ett symptom, hoppade över det misslyckade testet eller avbröt grundorsaksanalysen för tidigt. Åtgärden är en regel: ingen bugg stängs förrän ett test som fallerar på det gamla beteendet passerar på det nya och ansluter till sviten. Ta med en nylig återkommande bugg och fråga vilket skydd som skulle ha fångat den, för det skyddet är det ni saknade.

  3. Kan vi överhuvudtaget felsöka våra produktionssystem, med tanke på hur vi får röra dem? I företags- och särskilt myndighetsmiljöer kan ni ofta inte koppla en felsökare, inte reproducera med verkliga data och inte ändra ett körande system utan ett revisionsspår. Om er enda felsökningsteknik är en lokal interaktiv felsökare är ni blinda just där de svåraste buggarna bor. Fråga vilket belägg ett produktionsfel faktiskt lämnar efter sig: strukturerade loggar, distribuerade spår (kapitel 9.2), minnesdumpar eller reproducerbara byggartefakter. Besluta nu vad ni måste fånga som standard så att en framtida incident går att diagnostisera, eftersom ni inte kan lägga till instrumentering i ett fel som redan hänt. I reglerade miljöer, bekräfta att samma spår också uppfyller era revisionsskyldigheter.

  4. När en produktionsincident tvingar oss att stoppa blödningen snabbt, hur ser vi till att grundorsaken ändå hittas efteråt? Under en incident är en återställning eller en symptomlapp rätt första drag för att skydda användare, men faran är att ärendet stängs i samma stund som tjänsten återvänder och den underliggande defekten aldrig diagnostiseras. För ett stort team är det här där skuld ackumuleras osynligt, eftersom samma klass av fel dyker upp igen på en annan tjänst och hos en annan ingenjör med jour månader senare. Ta med era senaste allvarlighetsgrad-ett-incidenter och kontrollera var och en: följdes begränsningen av en reproduktion, en grundorsaksanalys och ett regressionsskydd, eller tog historien slut vid “tjänsten återställd”? Kom överens om en uttrycklig regel att en begränsad incident förblir öppen tills grundorsaken är förstådd och skyddad, och namnge vem som äger den uppföljningen. I företags- och myndighetsmiljöer, knyt detta till er incidenthanteringsprocess (kapitel 9.3) så att granskningen efter incidenten är ett krävt, granskningsbart steg snarare än en artighet som glider när nästa brand startar.

  5. Hur mycket av ett fel kan vi faktiskt rekonstruera i efterhand, och vem bestämde vad vi fångar som standard? Ni kan inte koppla instrumentering till ett fel som redan har hänt, så diagnostiserbarheten hos varje incident är fastställd i förväg av de loggar, spår, mått och dumpar ni valde att sända. Den motstridiga hänsynen är kostnad och brus: högkardinalitetshändelser och full spårning är inte gratis, och överloggning begraver signalen samtidigt som den blåser upp lagring och, i reglerade sammanhang, er exponering för datalagring. Ta med en verklig nylig incident och fråga vilket belägg den lämnade efter sig, arbeta sedan bakåt till vad ni önskar att ni hade fångat och vad det skulle kosta att behålla. Besluta medvetet vilka signaler som är på som standard mot samplade eller på begäran, och dokumentera det beslutet så att det är en policy, inte en olycka. För ett företags- eller myndighetssystem, lägg till vem som ansvarar för den observerbarhetsbudgeten och om det fångade spåret också uppfyller revisions-, integritets- och dataplaceringsskyldigheter.

  6. Behandlar vi felsökning som en undervisad, mätbar färdighet, eller tar nya ingenjörer in den genom osmos? Felsökning är lärbar, men de flesta team undervisar aldrig uttryckligen i den, så juniorer ärver den folklore som ligger närmast dem, och reproducera-först-metoden sprids ojämnt eller inte alls. Spänningen är att medveten undervisning (att para på svåra buggar, skriva ned fynd efter incidenter, följa mått) kostar senior tid som alltid känns behövd någon annanstans. Ta med två tal till diskussionen: er frekvens av upprepade defekter och er tid att diagnostisera, för om ni inte kan mäta dem kan ni inte avgöra om er metod förbättras eller förfaller. Överväg om introduktionen inkluderar en verklig felsökningsövning och om grundorsaksfynd faktiskt matar tidigare upptäckt. I en stor eller offentlig organisation blir en dokumenterad, mätt felsökningspraxis också belägg för teknisk stringens som revisorer, tillsynsmyndigheter och granskande organ alltmer förväntar sig att se.

Sektorsperspektiv

Startup. Med en handfull ingenjörer och ingen marginal är ditt mål att göra buggar billiga att reproducera och omöjliga att glömma, inte att bygga tung process. Lita på git bisect, en snabb lokal reproduktion och ett misslyckat test per åtgärdad bugg, eftersom den vanan kostar minuter och hindrar dig från att betala om för samma defekt medan du försöker leverera. Hoppa över formella efterhandsgranskningar, men hoppa aldrig över regressionstestet: det är den enda artefakten liten nog att alltid ha råd med och värdefull nog att alltid behålla.

Småföretag. Du har sannolikt ingen särskild tillförlitlighets- eller observerbarhetsspecialist och en snäv verktygsbudget, så föredra det din stack redan ger: läsbara stackspår, strukturerade loggar och den spårning som är inbyggd i de ramverk och hostade tjänster du har köpt. När du utvärderar en ny plattform, väg hur diagnostiserbar den gör fel, för ett billigt verktyg som döljer vad som gick fel kostar dig långt mer i gissningstid än licensen sparade. Reproducera-först och en-ändring-i-taget är gratis discipliner som betalar sig snabbast när ingen har timmar över.

Storföretag. Dina svåra buggar korsar tjänste- och teamgränser, så den som ser symptomet äger sällan orsaken, och en gemensam metod spelar större roll än någon enskild persons skicklighet. Standardisera reproducera-först, isolering med binärsökning, ett misslyckat test före rättelsen och skuldfria efterhandsgranskningar över team, och investera i distribuerad spårning (kapitel 9.2) så att en begäran kan följas över tjänster. Hantera felsökning som en mätt förmåga: följ frekvensen av upprepade defekter och tid att diagnostisera, och mata grundorsaksfynd tillbaka till tidigare upptäckt så att samma klass av fel inte turnerar på din tjänstekarta.

Offentlig sektor. Upphandlingsregler, begränsade miljöer och offentlig ansvarsskyldighet formar hur du överhuvudtaget får felsöka. Du kan ofta inte koppla en felsökare till produktion eller kopiera medborgardata till en laptop, så utforma för diagnos utifrån det som är tillåtet: reproducerbara byggen, syntetiska poster i en isolerad enklav och strukturerade loggar och spår fångade som standard. Dokumentera varje diagnostiskt steg och varje ändring i revisionsspåret, och kräv att leverantörer exponerar tillräckligt med telemetri och byggreproducerbarhet för att du ska kunna undersöka fel oberoende i stället för att förlita dig på leverantörens ord.

Exempel

Startup. Ett team på fyra ingenjörer ser hela tiden kassan fallera för en bråkdel av användarna, men aldrig i testning. I stället för att gissa fångar en ingenjör en pålitlig reproduktion genom att spela upp den exakta misslyckade begärans nyttolast, läser sedan stackspåret de hade ignorerat, som pekar på ett datumtolkningsanrop. En snabb git bisect över veckans commits namnger ändringen som bytte ett datumbibliotek. De skriver ett misslyckat test med den felande tidsstämpeln, åtgärdar tolkaren, ser testet bli grönt och behåller det i sviten. Hela undersökningen tar en eftermiddag eftersom de reproducerade innan de teoretiserade, och buggen återvänder aldrig.

Storföretag. En betalningsplattform ser intermittenta tidsgränsfel som inget enskilt team kan förklara, eftersom symptomet dyker upp i kassan men orsaken bor tre tjänster bort. Ingenjörer med jour använder distribuerad spårning (kapitel 9.2) för att följa en misslyckad begäran över tjänstegränser och hittar ett nedströmsanrop som ibland låser sig under samtidig belastning, ett klassiskt kapplöpningstillstånd där resultatet beror på otursamma tidpunkter mellan trådar. De reproducerar det med ett belastningstest, fångar det i ett misslyckat integrationstest, åtgärdar låsningen och kör en skuldfri efterhandsgranskning (kapitel 9.3) som lägger till ett spårningsspann och ett larm så att nästa förekomst fångas på minuter, inte dagar.

Offentlig sektor. En bidragsmyndighet kör sitt ärendesystem i en luftgapad miljö där ingenjörer inte kan koppla en felsökare till produktion och inte kan kopiera medborgardata till sina laptops. En beräkningsdefekt dyker upp i avstämningen. Teamet felsöker utifrån det miljön tillåter: strukturerade loggar, ett reproducerbart bygge de kan resa upp i en isolerad testenklav och syntetiska poster som återskapar det felande fallet. Varje diagnostiskt steg registreras i revisionsspåret, rättelsen levereras med ett test som först fallerar och sedan passerar som belägg, och grundorsaksanalysen matar en ny kontroll före release. Eftersom reproduktionen använde syntetiska data lämnade aldrig någon medborgarpost gränsen.

Affärsnytta: motiv, ROI och TCO

Avkastningen på disciplinerad felsökning mäts i ingenjörstimmar som inte läggs på att gissa och i defekter som inte återkommer. En odiagnostiserad intermittent bugg kan förbruka dagar av senior tid och upprepade eskaleringar för jour. En reproducera-först-metod förvandlar det till en avgränsad, delegerbar uppgift, och vanan med misslyckat test hindrar samma defekt från att debitera dig igen nästa kvartal. Över en stor organisation är den växande effekten av att aldrig betala om för samma bugg betydande, och den förbättrar direkt andelen misslyckade ändringar och genomsnittlig återställningstid som ledningen redan följer.

Den totala ägandekostnaden är mest utbildning och verktyg, och den är måttlig. Du behöver gemensamma konventioner (reproducera först, en ändring i taget, ett misslyckat test före rättelsen), felsökare och spårning som redan är vanliga i verktygskedjan och den observerbarhetsinvestering som beskrivs i kapitel 9.2. Den större, dolda kostnaden är alternativet: en kultur av vidskepelse där ingenjörer tillämpar ändringar med hagelbössa, symptom lappas och återkommer och jourbelastningen växer utan gräns. Att minska jourslit ensamt motiverar ofta investeringen, och argumentet inför ledningen är enklast formulerat som färre upprepade incidenter och snabbare återhämtning för en engångskostnad i vanor och instrumentering.

Antimönster och fallgropar

  • Felsökning med hagelbössa: att ändra många saker på en gång, så att även en rättelse inte lär dig något om orsaken.
  • Att åtgärda utan att reproducera: att förklara seger över en bugg du aldrig kunde utlösa på begäran.
  • Att ignorera felutdata: att teoretisera om orsaker som stackspåret redan uteslutit.
  • Symptomlappning: att tysta symptomet medan grundorsaken överlever och återkommer.
  • Spridning av utskriftssatser: utspridd felsökningsutdata som lämnats kvar i koden, vilket lägger till brus i stället för ett experiment knutet till en hypotes.
  • Att hoppa över regressionstestet: att åtgärda buggen men lämna inget skydd, så att den i det tysta kan komma tillbaka.
  • Omförsök av opålitliga tester: att dölja icke-determinism med omförsök i stället för att felsöka det underliggande kapplöpningstillståndet eller heisenbuggen, en bugg som ändras eller försvinner i samma stund du försöker observera den.
  • Skuldbelagda efterhandsgranskningar: att straffa författaren, vilket driver under jorden den information felsökning är beroende av.

Mognadsmodell

  • Nivå 1, Initiera: Felsökning är individuell folklore och reaktion. Ingenjörer gissar, tillämpar ändringar med hagelbössa och startar om saker. Buggar åtgärdas vid symptomet, reproduktioner är sällsynta och samma defekter återkommer. Produktion är knappt diagnostiserbar, och ingen kan lämna en bugg till någon annan eftersom inget försök är upprepbart.
  • Nivå 2, Utveckla: Vissa ingenjörer reproducerar pålitligt, läser stackspår och använder felsökare, men praxis är inkonsekvent och varierar från person till person och team till team. Loggning finns men är bullrig och ostrukturerad. Rättelser levereras ibland med ett misslyckat test, ofta inte, och grundorsaksanalys sker bara när någon insisterar.
  • Nivå 3, Standardisera: Reproducera-först, isolering med binärsökning, en ändring i taget och ett misslyckat test före rättelsen är dokumenterade teamnormer som upprätthålls i hela organisationen. Bisektion och reducering med delta-felsökning är vanlig praxis. Produktion har strukturerad loggning och spårning (kapitel 9.2), och skuldfria efterhandsgranskningar (kapitel 9.3) är standardsvaret för varje undkommen defekt.
  • Nivå 4, Hantera: Felsökningspraxis mäts och styrs mot utgångslägen. Frekvens av upprepade defekter, tid att diagnostisera, antal återöppnade ärenden och andelen rättelser som levererades med ett regressionstest följs per team och granskas i en takt. Reproduktion och slutförd grundorsak behandlas som grindar snarare än goda föresatser, och trender mot utgångsläget styr var ni investerar i verktyg, utbildning och observerbarhet.
  • Nivå 5, Orkestrera: Felsökning är en undervisad färdighet integrerad med kvalitet (kapitel 2.11) och incidenthantering (kapitel 9.3), och hela slingan anpassas kontinuerligt. Observerbarhet är inbyggd så att de flesta produktionsbuggar går att diagnostisera utan en felsökare, varje löst bugg stärker regressionssviten och grundorsaksfynd matar tidigare upptäckt så att klasser av defekter förebyggs snarare än diagnostiseras om. Organisationen omfördelar insats när dess system och felmönster utvecklas, och frekvensen av upprepade defekter fortsätter att falla.

Idéer för diskussion

  1. Hur stor andel av era senaste buggar reproducerades pålitligt innan någon ändrade kod, och vad säger den andelen om er metod?
  2. När en regression dyker upp, sträcker sig ert team efter bisektion, eller läser det kod för hand tills någon upptäcker den?
  3. Hur diagnostiserbart är ert produktionssystem i dag, och vad skulle ni ge för att ha fångat om ett fel som redan har hänt?
  4. Levereras era rättelser konsekvent med ett test som först fallerar och sedan passerar, och om inte, var bryter den disciplinen ihop?
  5. Hur hanterar ni opålitliga tester: felsöker ni icke-determinismen, eller döljer ni den med omförsök?
  6. Undervisas felsökning medvetet till nya ingenjörer, eller lämnas de att ta in folklore genom osmos?

Viktigaste punkter

  • Felsökning är hypotesprövning: reproducera pålitligt, läs felet och stackspåret och isolera sedan genom binärsökning och bisektion snarare än skanning.
  • Reducera felet till ett minimalt reproducerbart exempel, med delta-felsökning för stora indata, eftersom varje element som tas bort är en orsak som uteslutits.
  • Anpassa verktyget efter buggen: instrumentering och spårning för produktion och distribuerade system (kapitel 9.2), interaktiva felsökare för lokal undersökning.
  • Skriv ett misslyckat test som fångar buggen innan du åtgärdar den, så att rättelsen är bevisad och defekten skyddas mot för gott (kapitel 2.4).
  • Hitta och ta bort grundorsaken, kör skuldfria efterhandsgranskningar (kapitel 9.3) och behandla felsökning som en lärbar färdighet, inte folklore.
  • Ändra en sak i taget. Ändringar med hagelbössa och symptomlappar förstör belägg och bjuder tillbaka buggen.

Referenser och vidare läsning

  • David J. Agans, Debugging: The 9 Indispensable Rules for Finding Even the Most Elusive Software and Hardware Problems
  • Andreas Zeller, Why Programs Fail: A Guide to Systematic Debugging
  • Andreas Zeller and Ralf Hildebrandt, “Simplifying and Isolating Failure-Inducing Input” (the delta debugging algorithm)
  • Brian W. Kernighan and Rob Pike, The Practice of Programming (chapter on debugging)
  • Andrew Hunt and David Thomas, The Pragmatic Programmer (the chapters on debugging and assertions)
  • Steve McConnell, Code Complete: A Practical Handbook of Software Construction (the debugging chapter)
  • John Regehr, “Reducers Are Fuzzers” and related writing on test-case reduction
  • Charity Majors, Liz Fong-Jones, and George Miranda, Observability Engineering (debugging production with high-cardinality telemetry and tracing)
  • Betsy Beyer, Chris Jones, Jennifer Petoff, and Niall Richard Murphy, eds., Site Reliability Engineering (blameless postmortems and production debugging)