Wat is de moeilijkste bug je ooit gevonden en opgelost?

Wat maakte het moeilijk te vinden? Hoe heb je het opsporen?

Niet dicht genoeg bij in de buurt, maar zie ook
https://stackoverflow.com/questions/175854/what-is- de grappigste-bug-youve-ever-meegemaakt


1, Autoriteit 100%

Een jpeg parser, die draait op een bewakingscamera, die elke keer als CEO van het bedrijf kwam in de kamer is gecrasht.

100% reproduceerbaar fout.

Ik kid u niet!

Dit is de reden waarom:

Voor wie niet weet veel over JPEG-compressie – het beeld is een beetje opgesplitst in een matrix van kleine blokken die vervolgens worden gecodeerd met behulp van magie enz.

De parser verstikten wanneer de CEO in de kamer kwam, want hij had altijd een overhemd met een vierkant patroon op, die enkele bijzondere geval van contrast veroorzaakt en blokkeren grens algoritmen.

Echt klassieker.


2, Autoriteit 58%

Dit gebeurde niet voor mij, maar een vriend vertelde me over.

Hij moest een app die zeer zelden zou crashen debuggen. Het zou slechts falen op woensdag – in september – na de 9de. Ja, 362 dagen van het jaar, was het prima, en drie dagen van het jaar is het onmiddellijk zou crashen.

Het zou een datum als “woensdag 22 september, 2008” te formatteren, maar de buffer was een teken te kort – dus het alleen een probleem zou veroorzaken wanneer u een 2-cijferige DOM op een dag gehad met de langste naam in de maand met de langste naam.


3, gezag 30%

Dit vereist het kennen van een beetje van de Z-8000 assembler, die ik zal uitleggen als we gaan.

Ik werkte op een embedded systeem (in Z-8000 assembler). Een andere verdeling van het bedrijf was het bouwen van een ander systeem op hetzelfde platform, en had een bibliotheek van functies, die ik werd ook met behulp van op mijn project geschreven. De bug was dat elke keer als ik belde één functie, het programma crashte. Ik controleerde al mijn ingangen; ze waren prima. Het moest een bug in de bibliotheek zijn -., Behalve dat de bibliotheek was gebruikt (en werkte prima) in duizenden POS-locaties in het hele land

Nu, Z-8000 CPU 16 zijn 16-bit registers, R0, R1, R2 … R15, die tevens als 32 8-bits registers worden geadresseerd, genoemd RR0, RR2, RR4..RR14 enz bibliotheek werd vanuit het niets geschreven, refactoring een bos van oudere bibliotheken. Het was erg schoon en volgde strikte programmering normen. Aan het begin van elke functie, alle registers die worden gebruikt in de functie werd geduwd op de stapel om de waarde te behouden. Alles was netjes & amp; netjes. – ze waren perfect

Toch, bestudeerde ik de assembler lijst voor de bibliotheek, en ik merkte iets vreemds aan die functie — Aan het begin van de functie, het had PUSH RR0 / PUSH RR2 en aan het einde had POP RR2 / POP R0 . Nu, als je niet volgen dat, het duwde 4 waarden op de stapel bij de start, maar alleen verwijderd 3 van hen op het einde. Dat is een recept voor een ramp. Er een onbekende waarde op de bovenkant van de stapel, waar retouradres moesten zijn. De functie kon onmogelijk het werk.

Behalve, mag ik u eraan herinneren dat het werkte. Het werd duizenden keren riep een dag op duizenden machines. Het kon niet mogelijk niet werken.

Na enige tijd debugging (die niet gemakkelijk was in assembler op een embedded systeem met de instrumenten van het midden van de jaren 1980), zou het altijd crashen op het rendement, omdat de slechte waarde werd verzenden naar een willekeurig adres. Blijkbaar moest ik de werkende app debuggen, om erachter te komen waarom het niet mislukken.

Nou, bedenk dan dat de bibliotheek was zeer goed over het behoud van de waarden in de registers, dus zodra je er een waarde in het register, het bleef daar. R1 had 0000 in. Het zou altijd 0000 in het toen die functie werd genoemd. De fout dus zelf 0000 op de stapel. Dus wanneer de functie weer terug zou springen naar het adres van 0000, die net zo toevallig een RET, die de volgende waarde (de juiste retouradres) van de stapel zou pop, en naar die. De gegevens perfect gemaskeerd de bug.

Natuurlijk, in mijn aanvraag, ik had een andere waarde in R1, zodat het net neergestort ….


4, gezag 25%

Dit was op Linux, maar had op vrijwel elk besturingssysteem kunnen gebeuren. Nu zijn de meesten van jullie waarschijnlijk bekend met de BSD-socket-API. We gebruiken het jaar in jaar uit met veel plezier en het werkt.

We werkten aan een enorm parallelle applicatie die veel sockets open zou hebben. Om de werking ervan te testen, hadden we een testteam dat honderden en soms meer dan duizend verbindingen zou openen voor gegevensoverdracht. Met de hoogste kanaalnummers zou onze applicatie raar gedrag gaan vertonen. Soms crashte het gewoon. De andere keer kregen we fouten die gewoon niet waar konden zijn (bijv. accept() retourneerde dezelfde bestandsdescriptor bij volgende oproepen, wat natuurlijk tot chaos leidde.)

We konden in de logbestanden zien dat er iets mis ging, maar het was waanzinnig moeilijk te lokaliseren. Tests met Rational Purify wezen uit dat er niets aan de hand was. Maar er WAS iets mis. We hebben hier dagen aan gewerkt en raakten steeds meer gefrustreerd. Het was een showblocker omdat de reeds onderhandelde test voor ravage zou zorgen in de app.

Omdat de fout alleen optrad in situaties met hoge belasting, heb ik alles wat we met sockets deden dubbel gecontroleerd. We hadden nog nooit gevallen met hoge belasting getest in Purify omdat het niet haalbaar was in zo’n geheugenintensieve situatie.

Eindelijk (en gelukkig) herinnerde ik me dat het enorme aantal sockets een probleem zou kunnen zijn met select() dat wacht op statuswijzigingen op sockets (lees/mag schrijven/fout). Onze applicatie begon inderdaad grote schade aan te richten op het moment dat het de socket bereikte met descriptor 1025. Het probleem is dat select() werkt met bitveldparameters. De bitvelden worden gevuld door macro’s FD_SET() en vrienden die HUN PARAMETERS NIET CONTROLEREN OP GELDIGHEID.

Dus elke keer dat we meer dan 1024 descriptors hebben (elk besturingssysteem heeft zijn eigen limiet, Linux-vanilla-kernels hebben 1024, de werkelijke waarde is gedefinieerd als FD_SETSIZE), zou de FD_SET-macro graag zijn bitveld overschrijven en afval naar de volgende structuur schrijven in geheugen.

Ik heb alle select()-aanroepen vervangen door poll() wat een goed ontworpen alternatief is voor de mysterieuze select()-aanroep, en situaties met hoge belasting zijn nooit een probleem geweest. We hadden geluk omdat alle socket-afhandeling in één framework-klasse was waar 15 minuten werk het probleem kon oplossen. Het zou veel erger zijn geweest als select()-aanroepen over de hele code waren verspreid.

Leren geleerd:

  • zelfs als een API-functie 25 jaar oud is en iedereen hem gebruikt, kan hij donkere hoeken hebben die je nog niet kent

  • niet-aangevinkte geheugenschrijfacties in API-macro’s zijn EVIL

  • een debugging-tool als Purify kan niet in alle situaties helpen, vooral niet als er veel geheugen wordt gebruikt

  • Zorg indien mogelijk altijd voor een raamwerk voor uw toepassing. Het gebruik ervan verhoogt niet alleen de draagbaarheid, maar helpt ook in het geval van API-bugs

  • veel toepassingen gebruiken select() zonder na te denken over de socketlimiet. Dus ik ben er vrij zeker van dat je in VEEL populaire software bugs kunt veroorzaken door simpelweg veel sockets te gebruiken. Gelukkig zullen de meeste applicaties nooit meer dan 1024 sockets hebben.

  • In plaats van een veilige API te hebben, leggen OS-ontwikkelaars graag de schuld bij de ontwikkelaar. De Linux select() man-pagina zegt

“Het gedrag van deze macro’s is
undefined als een descriptorwaarde is
kleiner dan nul of groter dan of
gelijk aan FD_SETSIZE, wat normaal is
minstens gelijk aan het maximum aantal
van descriptoren ondersteund door de
systeem.”

Dat is misleidend. Linux kan meer dan 1024 sockets openen. En het gedrag is absoluut goed gedefinieerd: het gebruik van onverwachte waarden zal het draaien van de applicatie verpesten. In plaats van de macro’s bestand te maken tegen illegale waarden, overschrijven de ontwikkelaars gewoon andere structuren. FD_SET is geïmplementeerd als inline assembly (!) in de linux-headers en zal worden geëvalueerd tot een enkele assembler-schrijfinstructie. Er wordt nergens de minste grenscontrole uitgevoerd.

Om uw eigen applicatie te testen, kunt u het aantal gebruikte descriptors kunstmatig verhogen door programmatisch FD_SETSIZE-bestanden of sockets direct na main() te openen en vervolgens uw applicatie uit te voeren.

Thorsten79


Antwoord 5, autoriteit 22%

De mijne was een hardwareprobleem…

Vroeger gebruikte ik een DEC VaxStation met een grote 21-inch CRT-monitor. We verhuisden naar een laboratorium in ons nieuwe gebouw en installeerden twee VaxStations in tegenovergestelde hoeken van de kamer. Bij het opstarten flikkerde mijn monitor zoals een discotheek (ja, het waren de jaren 80), maar de andere monitor deed het niet.

Oké, verwissel de monitoren. De andere monitor (nu aangesloten op mijn VaxStation) flikkerde en mijn vorige monitor (die door de kamer bewoog) niet.

Ik herinnerde me dat CRT-monitoren gevoelig waren voor magnetische velden. In feite waren ze -zeer- gevoelig voor wisselende magnetische velden van 60 Hz. Ik vermoedde meteen dat iets in mijn werkgebied een wisselend magnetisch veld van 60 Hz opwekte.

Eerst vermoedde ik iets in mijn werkgebied. Helaas flikkerde de monitor nog steeds, zelfs als alle andere apparatuur was uitgeschakeld en losgekoppeld. Op dat moment begon ik iets in het gebouw te vermoeden.

Om deze theorie te testen, hebben we het VaxStation en zijn 85 lb-monitor omgebouwd tot een draagbaar systeem. We hebben het hele systeem op een rolkar geplaatst en verbonden met een oranje verlengsnoer van 30 meter lang. Het plan was om deze opstelling te gebruiken als draagbare veldsterktemeter om het gewraakte apparaat te lokaliseren.

Het rondrollen van de monitor bracht ons totaal in verwarring. De monitor flikkerde in precies de ene helft van de kamer, maar niet aan de andere kant. De kamer had de vorm van een vierkant, met deuren in tegenovergestelde hoeken, en de monitor flikkerde aan de ene kant van een diagonale lijn die de deuren verbond, maar niet aan de andere kant. De kamer was aan alle vier de zijden omgeven door gangen. We duwden de monitor de gangen in en het flikkeren stopte. We ontdekten zelfs dat het flikkeren alleen optrad in een driehoekige helft van de kamer, en nergens anders.

Na een periode van totale verwarring herinnerde ik me dat de kamer een tweerichtingssysteem voor plafondverlichting had, met lichtschakelaars bij elke deur. Op dat moment realiseerde ik me wat er mis was.

Ik heb de monitor naar de helft van de kamer met het probleem verplaatst en de plafondverlichting uitgedaan. Het flikkeren stopte. Toen ik de lichten aandeed, begon het flikkeren weer. Door de lichten aan of uit te zetten met een van de lichtschakelaars, werd de flikkering binnen de helft van de kamer in- of uitgeschakeld.

Het probleem werd veroorzaakt doordat iemand de hoek omsloeg bij het aansluiten van de plafondlampen. Bij het aansluiten van een tweerichtingsschakelaar op een verlichtingscircuit, voert u een paar draden uit tussen de SPDT-schakelaarcontacten en een enkele draad van de gemeenschappelijke op de ene schakelaar, door de lichten en naar de gemeenschappelijke op de andere schakelaar.

Normaal gesproken worden deze draden samen gebundeld. Ze vertrekken als een groep van de ene schakelkast, rennen naar de plafondarmatuur en verder naar de andere doos. Het belangrijkste idee is dat alle stroomvoerende draden samen worden gebundeld.

Toen het gebouw bedraad was, werd de enkele draad tussen de schakelaars en het licht door het plafond geleid, maar de draden die tussen de schakelaars liepen, werden door de muren geleid.

Als alle draden dicht bij elkaar en evenwijdig aan elkaar liepen, werd het magnetische veld dat door de stroom in één draad werd gegenereerd, tenietgedaan door het magnetische veld dat werd gegenereerd door de gelijke en tegengestelde stroom in een nabijgelegen draad. Helaas betekende de manier waarop de lichten waren bedraad dat de ene helft van de kamer zich in feite in een grote primaire transformator met één slag bevond. Toen de lichten aan waren, liep de stroom in een lus en de slechte monitor zat eigenlijk in een grote elektromagneet.

Moraal van het verhaal: de warme en neutrale lijnen in uw AC-stroombedrading liggen niet voor niets naast elkaar.

Nu hoefde ik alleen nog maar aan het management uit te leggen waarom ze een deel van hun nieuwe gebouw moesten herbekabelen…


Antwoord 6, autoriteit 17%

Een bug waarbij je wat code tegenkomt en na bestudering ervan concludeert: “Dit had nooit kunnen werken!” en plotseling stopt het met werken, hoewel het voorheen altijd werkte.


Antwoord 7, autoriteit 14%

Een van de producten die ik op mijn werk heb helpen bouwen, draaide enkele maanden op de site van een klant, waarbij elke gebeurtenis die het ontving werd verzameld en vastgelegd in een SQL Server-database. Het liep ongeveer 6 maanden heel goed en verzamelde ongeveer 35 miljoen records.

Op een dag vroeg onze klant ons waarom de database al bijna twee weken niet was bijgewerkt. Bij verder onderzoek ontdekten we dat de databaseverbinding die de invoegingen deed, niet was teruggekomen van de ODBC-aanroep. Gelukkig was de thread die de opname doet gescheiden van de rest van de threads, waardoor alles behalve de opnamethread bijna twee weken correct kon blijven functioneren!

We hebben wekenlang geprobeerd het probleem op een andere machine dan deze te reproduceren. We hebben het probleem nooit kunnen reproduceren. Helaas begonnen verschillende van onze andere producten toen op ongeveer dezelfde manier te falen, waarvan geen van de database-threads gescheiden was van de rest van hun functionaliteit, waardoor de hele applicatie vastliep, die vervolgens handmatig opnieuw moest worden gestart elke keer dat ze crashte.

Weken van onderzoek werden enkele maanden en we hadden nog steeds dezelfde symptomen: volledige ODBC-deadlocks in elke applicatie die we gebruikten een database. Tegen die tijd zitten onze producten vol met foutopsporingsinformatie en manieren om te bepalen wat er mis is gegaan en waar, zelfs tot het punt dat sommige producten de impasse detecteren, informatie verzamelen, ons de resultaten e-mailen en zichzelf vervolgens opnieuw opstarten.

Terwijl ik op een dag op de server werkte, nog steeds foutopsporingsinformatie verzamelde van de applicaties toen ze crashten, proberend te achterhalen wat er aan de hand was, de server BSoD op mij. Toen de server weer online kwam, opende ik de minidump in WinDbg om erachter te komen wat de overtredende driver was. Ik kreeg de bestandsnaam en traceerde het terug naar het eigenlijke bestand. Nadat ik de versie-informatie in het bestand had bekeken, kwam ik erachter dat het onderdeel was van de McAfee-antivirussuite die op de computer was geïnstalleerd.

We hebben de antivirus uitgeschakeld en hebben sindsdien geen enkel probleem meer gehad!!


Antwoord 8, autoriteit 13%

Ik wil alleen wijzen op een vrij veel voorkomende en vervelende bug die kan optreden in deze tijd van Google:
code plakken en de beruchte min

Dat is wanneer je een code kopieert met een minin het, in plaats van een normaal ASCII-teken koppelteken-min (‘-‘).


Plus, min(U+2212), koppelteken-min(U+002D)

Ook al wordt de min zogenaamd weergegeven als langer dan het koppelteken-min, op bepaalde editors (of op een DOS-shellvenster), afhankelijk van de gebruikte tekenset, wordt het in feite weergegeven als een gewoon ‘-‘-streepje- minteken.

En… je kunt uren besteden aan het uitzoeken waarom deze code niet compileert, waarbij je elke regel één voor één verwijdert, totdat je de werkelijke oorzaak hebt gevonden!

Misschien niet de moeilijkste bug die er is, maar frustrerend genoeg 😉

(Bedankt ShreevatsaRvoor het zien van de inversie in mijn oorspronkelijke bericht – zie opmerkingen)


Antwoord 9, autoriteit 10%

De eerste was dat ons uitgebrachte product een bug vertoonde, maar toen ik probeerde het probleem op te lossen, deed het zich niet voor. Ik dacht eerst dat dit een “release vs. debug”-ding was — maar zelfs toen ik de code in de release-modus compileerde, kon ik het probleem niet reproduceren. Ik ging kijken of een andere ontwikkelaar het probleem kon reproduceren. Nee. Na veel onderzoek (het produceren van een gemengde assemblagecode / C-codelijst) van de programma-uitvoer en het doorlopen van de assemblagecode van het vrijgegeven product (bah!), vond ik de beledigende regel. Maar de lijn zag er prima uit voor mij! Ik moest toen opzoeken wat de montage-instructies deden – en inderdaad, de verkeerde montage-instructie stond in het vrijgegeven uitvoerbare bestand. Daarna controleerde ik het uitvoerbare bestand dat mijn bouwomgeving produceerde — het had de juiste montage-instructie. Het bleek dat de bouwmachine op de een of andere manier corrupt was geraakt en slechte montagecode produceerde voor slechts één instructie voor deze toepassing. Al het andere (inclusief eerdere versies van ons product) produceerde identieke code voor andere ontwikkelaarsmachines. Nadat ik mijn onderzoek aan de softwaremanager had laten zien, bouwden we snel onze bouwmachine opnieuw.


Antwoord 10, autoriteit 8%

Ergens diep in de ingewanden van een netwerktoepassing was de regel (vereenvoudigd):

if (socket = accept() == 0)
    return false;
//code using the socket()

Wat gebeurde er toen het gesprek lukte? socketis ingesteld op 1. Wat doet send()als een 1 wordt gegeven? (zoals in:

send(socket, "mystring", 7);

Het drukt af naar stdout… dit ontdekte ik na 4 uur afvragen waarom, met al mijn printf()‘s verwijderd, mijn app aan het afdrukken was naar de terminalvenster in plaats van de gegevens over het netwerk te verzenden.


Antwoord 11, autoriteit 8%

Met FORTRAN op een Data General-minicomputer in de jaren 80 hadden we een geval waarin de compiler ervoor zorgde dat een constante 1 (één) werd behandeld als 0 (nul). Het gebeurde omdat een oude code een constante van waarde 1 doorgaf aan een functie die de variabele als een FORTRAN-parameter verklaarde, wat betekende dat deze (verondersteld) onveranderlijk was. Vanwege een defect in de code hebben we een toewijzing aan de parametervariabele gedaan en de compiler heeft de gegevens op de gebruikte geheugenlocatie vrolijk gewijzigd voor een constante 1 tot 0.

Veel niet-gerelateerde functies later hadden we code die een vergelijking maakte met de letterlijke waarde 1 en de test zou mislukken. Ik herinner me dat ik het langst naar die code staarde in de debugger. Ik zou de waarde van de variabele afdrukken, het zou 1 zijn, maar de test ‘if (foo .EQ. 1)’ zou mislukken. Het duurde lang voordat ik dacht de debugger te vragen om uit te printen wat hij dacht dat de waarde van 1 was. Het kostte veel moeite om de code terug te vinden wanneer de constante 1 0 werd.


Antwoord 12, autoriteit 6%

Ik had een fout in een consolegame die zich pas voordeed nadat je had gevochten en een langdurig gevecht met de baas had gewonnen, en toen slechts ongeveer 1 keer op de 5. Als het werd geactiveerd, bleef de hardware 100% vastzitten en kon niet praten helemaal naar de buitenwereld.

Het was de meest verlegen bug die ik ooit ben tegengekomen; het aanpassen, automatiseren, instrumenteren of debuggen van de boss-battle zou de bug verbergen (en natuurlijk zou ik 10-20 runs moeten doen om te bepalen dat de bug verborgen was).

Uiteindelijk vond ik het probleem (een cache/DMA/interrupt race-ding) door de code 2-3 dagen lang opnieuw en opnieuw te lezen.


Antwoord 13, autoriteit 6%

Niet erg moeilijk, maar ik heb veel gelachen toen het werd ontdekt.

Toen ik een 24/7 orderverwerkingssysteem voor een online winkel aan het onderhouden was, klaagde een klant dat zijn bestelling “afgekapt” was. Hij beweerde dat hoewel de bestelling die hij plaatste eigenlijk N posities bevatte, het systeem veel minder posities accepteerde zonder enige waarschuwing.

Nadat we de orderstroom door het systeem hadden getraceerd, kwamen de volgende feiten aan het licht. Er was een opgeslagen procedure die verantwoordelijk was voor het opslaan van bestelitems in de database. Het accepteerde een lijst met bestelitems als tekenreeks, die de gecodeerde lijst van (product-id, quantity, price)als volgt verdrievoudigt:

“<12345, 3, 19,99><56452, 1,
8.99><26586, 2, 12.99>”

Nu, de auteur van opgeslagen procedure was te slim om toevlucht te nemen tot iets als gewone parsing en looping. Dus hij direct de string in SQL multi-insert statement getransformeerd door het vervangen van "<"met "insert into ... values ("en ">"met ");". Dat was allemaal leuk en aardig, al was het maar heeft hij niet te slaan resulterende tekenreeks in een varchar (8000) variabele!

Wat gebeurd is, is dat zijn "insert ...; insert ...;"is afgekapt in 8000 karakter en voor die bepaalde volgorde de snede was “lucky” genoeg te gebeuren precies tussen insertis, zodat ingekorte SQL bleef syntactisch correct .

Later ontdekte ik de auteur van sp was mijn baas.


14, autoriteit 6%

Dit is terug toen ik dacht dat C++ en digitale horloges waren vrij netjes …

Ik heb een reputatie voor het kunnen moeilijk geheugenlekken te lossen. Een ander team had een lek ze niet konden opsporen. Ze vroegen me om te onderzoeken.

In dit geval waren ze COM-objecten. In de kern van het systeem was een onderdeel dat veel bochtige weinig COM objecten die allemaal min of meer hetzelfde uitzag gaf. Ieder werd uitgedeeld aan veel verschillende klanten, die elk verantwoordelijk was voor het doen van AddRef()en Release()hetzelfde aantal keren.

Er was niet een manier om automatisch te berekenen die elkaar AddRef, en of ze hadden Released had gebeld.

Ik heb een paar dagen in de debugger, het opschrijven van hex-adressen op kleine stukjes papier. Mijn kantoor was bedekt met hen. Uiteindelijk vond ik de boosdoener. Het team dat me om hulp gevraagd was erg dankbaar.

De volgende dag ben ik overgestapt naar een GC’d taal. *

(* Niet echt waar, maar zou een goede einde aan het verhaal.)


15, autoriteit 6%

Bryan Cantrill van Sun Microsystems gaf een uitstekende Google Tech Talk op een bug hij opgespoord met behulp van een instrument dat hij bijgedragen aan de ontwikkeling genaamd dtrace.

De De Tech Talk is grappig , geeky, informatief en zeer indrukwekkend (en lang , ongeveer 78 minuten).

Ik zal geen spoilers hier over wat de bug was, maar hij begint het openbaren van de dader om ongeveer 53:00.


16, autoriteit 6%

Tijdens het testen van een aantal nieuwe functies die ik onlangs had toegevoegd aan een trading toepassing, ik toevallig op te merken dat de code om de resultaten van een bepaald type van de handel weer te geven zou nooit goed werken. Na het kijken naar de bron besturingssysteem, was het duidelijk dat deze bug had bestaan ​​voor minstens een jaar, en ik was verbaasd dat geen van de handelaren ooit had gespot.

Na puzzelen voor een tijdje en het controleren met een collega, ik vast de bug en ging op het testen van mijn nieuwe functionaliteit. Ongeveer 3 minuten later, ging mijn telefoon. Aan de andere kant van de lijn was een woedende handelaar die klaagden dat een van zijn transacties niet correct was resultaat.

Bij nader onderzoek, realiseerde ik me dat de handelaar hit met exact dezelfde fout ik in de code 3 minuten eerder had opgemerkt was geweest. Deze bug lag al rond voor een jaar, klaar voor een ontwikkelaar om mee te gaan en spot het zo dat het zou kunnen treffen voor de echte.

Dit is een goed voorbeeld van een soort insect bekend als Schroedinbug . Terwijl de meeste van ons over deze eigenaardige entiteiten hebben gehoord, het is een mysterieuze gevoel als je daadwerkelijk tegenkomen één in het wild.


17, autoriteit 4%

De twee zwaarste bugs die te binnen schieten werden beide in hetzelfde type software was er maar één in de web-based versie, en een in de Windows-versie.

Dit product is een plattegrondviewer/editor. De webversie heeft een flash-front-end die de gegevens als SVG laadt. Dit werkte prima, alleen liep de browser soms vast. Alleen op een paar tekeningen, en alleen als je even met de muis over de tekening beweegt. Ik heb het probleem teruggebracht tot een enkele tekenlaag, die 1,5 MB aan SVG-gegevens bevat. Als ik slechts een subsectie van de gegevens nam, een subsectie, vond het vastlopen niet plaats. Uiteindelijk drong het tot me door dat het probleem waarschijnlijk was dat er verschillende secties in het bestand waren die in combinatie de bug veroorzaakten. En ja hoor, na het willekeurig verwijderen van secties van de laag en het testen op de bug, vond ik de beledigende combinatie van tekeninstructies. Ik heb een tijdelijke oplossing geschreven in de SVG-generator en de bug is verholpen zonder een regel actionscript te wijzigen.

In hetzelfde product aan de vensterzijde, geschreven in Delphi, hadden we een vergelijkbaar probleem. Hier neemt het product autocad DXF-bestanden, importeert ze naar een intern tekenformaat en rendert ze in een aangepaste tekenengine. Deze importroutine is niet bijzonder efficiënt (het gebruikt veel substring-kopieën), maar het klaart de klus. Alleen in dit geval niet. Een bestand van 5 megabyte wordt over het algemeen in 20 seconden geïmporteerd, maar bij één bestand duurde het 20 minuten, omdat de geheugenvoetafdruk opliep tot een gigabyte of meer. In eerste instantie leek het een typisch geheugenlek, maar geheugenlektools meldden het schoon en handmatige code-inspectie leverde ook niets op. Het probleem bleek een bug te zijn in de geheugentoewijzer van Delphi 5. In sommige omstandigheden, die dit specifieke bestand naar behoren opnieuw maakte, zou het vatbaar zijn voor ernstige geheugenfragmentatie. Het systeem zou blijven proberen om grote strings toe te wijzen, en nergens vinden om ze te plaatsen, behalve boven het hoogst toegewezen geheugenblok. Het integreren van een nieuwe bibliotheek voor geheugentoewijzing loste de bug op, zonder een regel importcode te wijzigen.

Als ik eraan terugdenk, lijken de moeilijkste bugs de bugs te zijn waarvan de oplossing het veranderen van een ander deel van het systeem inhoudt dan dat waar het probleem zich voordoet.


Antwoord 18, autoriteit 4%

Toen het konijntje van de klant halverwege de ethernetkabel knaagde. Ja. Het was slecht.


Antwoord 19, autoriteit 4%

Er was een bug op een platform met een zeer slechte debugger op het apparaat.
We zouden een crashop het apparaat krijgen als we een printfaan de code zouden toevoegen. Het zou dan op een andere plek crashen dan de locatie van de printf. Als we de printf zouden verplaatsen, zou de crash zich verplaatsen of verdwijnen. Als we die code zouden wijzigen door enkele eenvoudige instructies opnieuw te ordenen, zou de crash zelfs plaatsvinden als deze niet gerelateerd was aan de code die we wel hebben gewijzigd.

Het bleek dat er een bug in de relocator voor ons platform zat.de relocator was niet nul bij het initialiseren van de ZI-sectie, maar gebruikte eerder de relocatietabel om de waarden te initialiseren. Dus elke keer dat de verplaatsingstabel in het binaire bestand veranderde, zou de bug worden verplaatst. Dus gewoon een printf toevoegen zou de verplaatsingstabel veranderen en daar voor de bug.


Antwoord 20, autoriteit 4%

Dit overkwam mij in de tijd dat ik in een computerwinkel werkte.

Een klant kwam op een dag de winkel binnen en vertelde ons dat zijn gloednieuwe computer ‘s avonds en ‘s nachts prima werkte, maar ‘s middags of ‘s avonds laat helemaal niet.
Het probleem was dat de muisaanwijzer op dat moment niet beweegt.

Het eerste wat we deden was zijn muis vervangen door een nieuwe, maar de problemen waren niet verholpen. Natuurlijk werkten beide muizen probleemloos in de winkel.

Na verschillende pogingen ontdekten we dat het probleem bij dat specifieke merk en model muis zat.
Het werkstation van de klant bevond zich dicht bij een heel groot raam en ‘s middags stond de muis in direct zonlicht.
Het plastic was zo dun dat het onder die omstandigheden doorschijnend werd en zonlicht verhinderde dat het optomechanische wiel werkte:|


Antwoord 21, autoriteit 4%

Mijn team heeft een CGI-gebaseerde, multi-threaded C++ web-app geërfd. Het hoofdplatform was Windows; Een verre, secundair platform was Solaris met Posix-threads. Stabiliteit op Solaris was om een ​​of andere reden een ramp. We hadden verschillende mensen die al meer dan een jaar naar het probleem keken, uit (meestal uitgeschakeld), terwijl onze verkooppersoneel met succes de Windows-versie heeft geduwd.

Het symptoom was zielige stabiliteit: een breed scala aan systeem crasht met weinig rijm of reden. De app gebruikte zowel CORBA als een thuisgekweekt protocol. Eén ontwikkelaar ging voor zover om het hele CORBA-subsysteem te verwijderen als een wanhopige maatregel: geen geluk.

Eindelijk, een senior, vroeg de originele ontwikkelaar zich voor om een ​​idee. We keken erin en vonden uiteindelijk het probleem: op Solaris, was er een parameter voor compileren (of runtime?) Om de stapelgrootte voor het uitvoerbare bestand aan te passen. Het werd onjuist ingesteld: veel te klein. Dus de app liep uit de stapel en het afdrukken van stapelsporen die totaal rode herhaling waren.

Het was een echte nachtmerrie.

Lessen geleerd:

  • brainstorm, brainstorm, brainstorm
  • Als iets noten op een ander, verwaarloosd platform gaat, is het waarschijnlijk een attribuut van het milieuplatform
  • Pas op voor problemen die worden overgedragen van ontwikkelaars die het team verlaten. Neem indien mogelijk contact op met de vorige mensen op persoonlijke basis aan Garner-info en achtergrond. Smeken, pleiten, maak een deal. Het verlies van ervaring moet ten minste worden geminimaliseerd.

Antwoord 22, autoriteit 3%

Het was tijdens mijn afstudeerscriptie. Ik was een programma aan het schrijven om het effect van een laser met hoge intensiteit op een heliumatoom te simuleren met FORTRAN.

Eén testrun werkte als volgt:

  • Bereken de initiële kwantumtoestand met programma 1, ongeveer 2 uur.
  • voer de hoofdsimulatie uit op de gegevens van de eerste stap, voor de meest eenvoudige gevallen ongeveer 20 tot 50 uur.
  • analyseer vervolgens de uitvoer met een derde programma om betekenisvolle waarden te krijgen zoals energie, tork, momentum

Deze zouden in totaal constant moeten zijn, maar dat waren ze niet. Ze deden allerlei rare dingen.

Na twee weken debuggen ging ik als een speer door het loggen en registreerde elke variabele in elke stap van de simulatie, inclusief de constanten.

Op die manier kwam ik erachter dat ik over een einde van een array schreef, wat een constante veranderde!

Een vriend zei dat hij ooit de letterlijke 2 met zo’n fout had veranderd.


Antwoord 23, autoriteit 2%

Een impasse in mijn eerste multi-threaded programma!

Het was erg moeilijk om het te vinden omdat het gebeurde in een threadpool. Af en toe liep een draad in het zwembad vast, maar de andere zouden nog steeds werken. Omdat de grootte van het zwembad veel groter was dan nodig was, duurde het een week of twee voordat het eerste symptoom werd opgemerkt: de applicatie liep volledig vast.


Antwoord 24, autoriteit 2%

Ik heb uren tot dagen besteed aan het debuggen van een aantal dingen die uiteindelijk konden worden opgelost met letterlijk slechts een paar tekens.

Enkele verschillende voorbeelden:

  1. ffmpeg heeft de nare gewoonte om een ​​waarschuwing te geven over “brainfart cropping” (verwijzend naar een geval waarin in-stream bijsnijdwaarden >= 16 zijn) terwijl de uitsnijdingswaarden in de stream eigenlijk perfect geldig waren. Ik heb het opgelost door drie tekens toe te voegen: “h->”.

  2. x264 had een bug waarbij het in uiterst zeldzame gevallen (één op de miljoen frames) met bepaalde opties een willekeurig blok van volledig de verkeerde kleur zou produceren. Ik heb de bug verholpen door de letter “O” op twee plaatsen in de code toe te voegen. Bleek dat ik de naam van een #define verkeerd had gespeld in een eerdere commit.


Antwoord 25, autoriteit 2%

Mijn eerste “echte” baan was voor een bedrijf dat client-server sales-force automatiseringssoftware schreef. Onze klanten draaiden de client-app op hun (15-pond) laptops en aan het eind van de dag belden ze naar onze Unix-servers om te synchroniseren met de Mother-database. Na een reeks klachten ontdekten we dat een astronomisch aantal oproepen in het begin, tijdens de authenticatie, afnam.

Na weken van debuggen ontdekten we dat de authenticatie altijdmislukt als de inkomende oproep werd beantwoord door een getty-proces op de server waarvan de proces-ID een even nummer bevatte, onmiddellijk gevolgd door een 9. Blijkt de authenticatie was een zelfgemaakt schema dat afhing van een 8-tekenreeksrepresentatie van de PID; een bug zorgde ervoor dat een beledigende PID de getty liet crashen, die opnieuw verscheen met een nieuwe PID. De tweede of derde oproep vond meestal een acceptabele PID, en automatisch opnieuw kiezen maakte het voor de klanten niet nodig om in te grijpen, dus het werd niet als een groot probleem beschouwd totdat de telefoonrekeningen aan het einde van de maand arriveerden.

De “fix” (ahem) was om de PID om te zetten in een tekenreeks die de waarde in octalvertegenwoordigt in plaats van decimaal, waardoor het onmogelijk wordt om een ​​9 te bevatten en het onnodig is om het onderliggende probleem aan te pakken.


Antwoord 26, autoriteit 2%

Eigenlijk alles wat met threads te maken heeft.

Ik heb ooit een functie gehad bij een bedrijf waarin ik de twijfelachtige onderscheiding had een van de weinige mensen te zijn die vertrouwd genoeg was met threading om vervelende problemen op te lossen. De horror. Je zou een soort certificering moeten behalen voordat je threaded code mag schrijven.


Antwoord 27, autoriteit 2%

Ik hoorde op de middelbare school over een klassieke bug; een terminal waar je alleen op kon inloggen als je ervoor in de stoel zat. (Het zou je wachtwoord weigeren als je stond.)

Het reproduceerde redelijk betrouwbaar voor de meeste mensen; je zou in de stoel kunnen zitten, inloggen, uitloggen… maar als je opstaat, wordt je elke keer geweigerd.

Uiteindelijk bleek dat een of andere eikel een paar aangrenzende toetsen op het toetsenbord, E/R en C/V IIRC, had verwisseld, en toen je ging zitten, typte je op de toetsen en stapte in, maar toen je opstond, had je om te jagen en pikken, dus je keek naar de verkeerde labels en faalde.


Antwoord 28, autoriteit 2%

Hoewel ik me geen specifiek exemplaar herinner, zijn de moeilijkste categorie die bugs die zich pas manifesteren nadat het systeem uren of dagen heeft gedraaid, en wanneer het uitvalt, weinig of geen spoor achterlaat van de oorzaak van de crash. Wat ze bijzonder slecht maakt, is dat, hoe goed je ook denkt de oorzaak te hebben beredeneerd en de juiste oplossing hebt toegepast om het te verhelpen, je nog een paar uur of dagen moet wachten om enig vertrouwen te krijgen in wat je heb het echt goed gedaan.


Antwoord 29, autoriteit 2%

Onze netwerkinterface, een DMA-compatibele ATM-kaart, leverde heel af en toe beschadigde gegevens in ontvangen pakketten. De AAL5 CRC was als correct uitgecheckt toen het pakket via de kabel binnenkwam, maar de data DMAd naar het geheugen zou onjuist zijn. De TCP-controlesom zou het over het algemeen opvangen, maar in de onstuimige dagen van ATM waren mensen enthousiast over het rechtstreeks draaien van native applicaties op AAL5, waarbij TCP/IP helemaal niet meer nodig was. We merkten uiteindelijk dat de corruptie alleen optrad op sommige modellen van het werkstation van de leverancier (die naamloos zullen blijven), en niet op andere.

Door de CRC in de stuurprogrammasoftware te berekenen, konden we de beschadigde pakketten detecteren, ten koste van een enorme prestatiehit. Terwijl we probeerden te debuggen, merkten we dat als we het pakket een tijdje zouden bewaren en er later naar zouden kijken, de datacorruptie zichzelf op magische wijze zou genezen. De pakketinhoud zou in orde zijn, en als de bestuurder de CRC een tweede keer zou berekenen, zou het goed zijn.

We hadden een fout gevonden in de gegevenscache van een verzend-CPU. De cache in deze processor was niet coherent met DMA, waardoor de software deze expliciet op de juiste momenten moest wissen. De bug was dat de cache soms niet echt de inhoud wist wanneer dit werd gevraagd.

Other episodes