Ohjelmoijien ja insinöörien kansanperinne (osa 1)

Ohjelmoijien ja insinöörien kansanperinne (osa 1)

Tämä on valikoima tarinoita Internetistä siitä, kuinka bugeilla on joskus täysin uskomattomia ilmentymiä. Ehkä sinullakin on jotain kerrottavaa.

Auton allergia vaniljajäätelölle

Tarina insinööreille, jotka ymmärtävät, että ilmeinen ei aina ole vastaus ja että vaikka tosiasiat näyttävät kuinka kaukaa haetuilta, ne ovat silti tosiasioita. General Motors Corporationin Pontiac-divisioona sai valituksen:

Tämä on toinen kerta, kun kirjoitan sinulle, enkä syytä sinua siitä, että et vastaa, koska se kuulostaa hullulta. Perheellämme on perinne syödä jäätelöä joka ilta päivällisen jälkeen. Jäätelölajit vaihtuvat joka kerta, ja päivällisen jälkeen koko perhe valitsee minkä jäätelön ostaa, jonka jälkeen menen kauppaan. Ostin äskettäin uuden Pontiacin, ja siitä lähtien jäätelön hankinnastani on tullut ongelma. Aina kun ostan vaniljajäätelöä ja palaan kaupasta, auto ei käynnisty. Jos tuon muuta jäätelöä, auto lähtee käyntiin ilman ongelmia. Haluan esittää vakavan kysymyksen, vaikka se kuulostaa kuinka tyhmältä: "Mikä Pontiacissa on, että se ei käynnisty, kun tuon vaniljajäätelöä, vaan käynnistyy helposti, kun tuon toisen maun jäätelöä?"

Kuten voitte kuvitella, divisioonan johtaja suhtautui kirjeeseen skeptisesti. Lähetin kuitenkin varmuuden vuoksi insinöörin tarkistamaan. Hän oli yllättynyt, että hänet kohtasi varakas, hyvin koulutettu mies, joka asui kauniilla alueella. He sopivat tapaavansa heti illallisen jälkeen, jotta he voisivat mennä kauppaan jäätelölle. Sinä iltana se oli vaniljaa, ja kun he palasivat autoon, se ei käynnistynyt.

Insinööri tuli vielä kolme iltaa. Ensimmäisellä kerralla jäätelö oli suklaata. Auto käynnistyi. Toisella kerralla oli mansikkajäätelöä. Auto käynnistyi. Kolmantena iltana hän pyysi vaniljaa. Auto ei lähtenyt käyntiin.

Järkevästi päätellen insinööri kieltäytyi uskomasta, että auto olisi allerginen vaniljajäätelölle. Siksi sovin auton omistajan kanssa, että hän jatkaa vierailujaan, kunnes hän löytää ratkaisun ongelmaan. Ja matkan varrella hän alkoi tehdä muistiinpanoja: hän kirjoitti muistiin kaikki tiedot, kellonajan, bensiinin tyypin, saapumis- ja paluuajan kaupasta jne.

Insinööri huomasi pian, että auton omistaja käytti vähemmän aikaa vaniljajäätelön ostamiseen. Syynä oli tavaroiden asettelu myymälässä. Vaniljajäätelö oli suosituin ja sitä säilytettiin erillisessä pakastimessa kaupan etuosassa, jotta se olisi helpompi löytää. Ja kaikki muut lajikkeet olivat myymälän takaosassa, ja oikean lajikkeen ja maksun löytäminen vei paljon enemmän aikaa.

Nyt kysymys oli insinöörille: miksi auto ei käynnistynyt, jos moottorin sammuttamisen hetkestä oli kulunut vähemmän aikaa? Koska ongelma oli aika, ei vaniljajäätelö, insinööri löysi nopeasti vastauksen: se oli kaasulukko. Se tapahtui joka ilta, mutta kun auton omistaja vietti enemmän aikaa jäätelön etsimiseen, moottori ehti jäähtyä tarpeeksi ja käynnistyi helposti. Ja kun mies osti vaniljajäätelöä, moottori oli vielä liian kuuma eikä kaasulukko ehtinyt liueta.

Moraali: Jopa täysin hullut ongelmat ovat joskus todellisia.

Crash Bandicoot

Tämän kokeminen on tuskallista. Ohjelmoijana tottuu syyttelemään koodiasi ensin, toiseksi, kolmanneksi... ja jossain kymmenentuhannen puolella syyttelet kääntäjää. Ja alempana luettelossa syytät jo laitteita.

Tässä on tarinani laitteistovirheestä.

Crash Bandicoot -peliä varten kirjoitin koodin, joka ladataan ja tallennetaan muistikortille. Tällaiselle omahyväiselle pelikehittäjälle se oli kuin kävely puistossa: luulin, että työ kestää useita päiviä. Päädyin kuitenkin koodin virheenkorjaukseen kuuden viikon ajan. Matkan varrella ratkaisin muita ongelmia, mutta muutaman päivän välein palasin tähän koodiin muutaman tunnin ajan. Se oli tuskaa.

Oire näytti tältä: kun tallennat pelin nykyisen läpikäynnin ja käytät muistikorttia, kaikki menee melkein aina hyvin... Mutta joskus luku- tai kirjoitustoiminto aikakatkaisee ilman selvää syytä. Lyhyt tallennus vahingoittaa usein muistikorttia. Kun pelaaja yrittää pelastaa, hän ei vain epäonnistu, vaan myös tuhoaa kartan. Paska.

Jonkin ajan kuluttua tuottajamme Sonylla Connie Bus alkoi panikoida. Emme voineet lähettää peliä tämän bugin kanssa, ja kuusi viikkoa myöhemmin en ymmärtänyt, mikä ongelman aiheutti. Connien kautta otimme yhteyttä muihin PS1-kehittäjiin: onko kukaan törmännyt vastaavaan? Ei. Kenelläkään ei ollut ongelmia muistikortin kanssa.

Kun sinulla ei ole ideoita virheenkorjaukseen, ainoa jäljellä oleva tapa on "hajauttaa ja hallita": poistaa yhä enemmän koodia viallisesta ohjelmasta, kunnes jäljellä on suhteellisen pieni fragmentti, joka edelleen aiheuttaa ongelman. Eli katkaiset ohjelman pala palalta, kunnes vian sisältävä osa jää jäljelle.

Mutta asia on, että videopelistä on erittäin vaikea leikata paloja. Kuinka ajaa se, jos poistit painovoimaa emuloivan koodin? Tai piirtää hahmoja?

Siksi meidän on korvattava kokonaisia ​​moduuleja tyngillä, jotka teeskentelevät tekevänsä jotain hyödyllistä, mutta itse asiassa tekevät jotain hyvin yksinkertaista, joka ei voi sisältää virheitä. Meidän on kirjoitettava tällaiset kainalosauvat, jotta peli ainakin toimisi. Tämä on hidas ja tuskallinen prosessi.

Lyhyesti sanottuna tein sen. Poistin yhä enemmän koodinpätkiä, kunnes minulle jäi alkuperäinen koodi, joka määrittää järjestelmän suorittamaan peliä, alustaa renderöintilaitteiston jne. Tietenkään tässä vaiheessa en voinut luoda tallennus- ja latausvalikkoa, koska minun piti luoda tynkä kaikille grafiikkakoodille. Mutta voisin teeskennellä olevani käyttäjä, joka käyttää (näkymätöntä) tallennus- ja latausnäyttöä ja pyytää tallentaa ja kirjoittaa muistikortille.

Tästä jäi minulle pieni koodinpätkä, jossa oli edelleen yllä oleva ongelma - mutta se tapahtui silti satunnaisesti! Useimmiten kaikki toimi hyvin, mutta välillä oli vikoja. Poistin melkein kaiken pelikoodin, mutta bugi oli edelleen elossa. Tämä oli hämmentävää: jäljellä oleva koodi ei oikeastaan ​​tehnyt mitään.

Jossain vaiheessa, luultavasti kolmen aikaan aamulla, mieleeni tuli ajatus. Luku- ja kirjoitustoiminnot (syöttö/tulostus) sisältävät tarkat suoritusajat. Kun työskentelet kiintolevyn, muistikortin tai Bluetooth-moduulin kanssa, lukemisesta ja kirjoittamisesta vastaava matalan tason koodi tekee sen kellopulssien mukaan.

Kellon avulla laite, joka ei ole suoraan kytketty prosessoriin, synkronoidaan prosessorilla suoritettavan koodin kanssa. Kello määrittää tiedonsiirtonopeuden – tiedonsiirtonopeuden. Jos ajoituksissa on sekaannusta, myös laitteisto tai ohjelmisto tai molemmat ovat sekaisin. Ja tämä on erittäin huono asia, koska tiedot voivat vaurioitua.

Entä jos jokin koodissamme sekoittaa ajoitukset? Tarkistin testiohjelmakoodista kaiken tähän liittyvän ja huomasin, että asetimme ohjelmoitavan ajastimen PS1:ssä 1 kHz:iin (1000 tikkua sekunnissa). Tämä on melko paljon; oletusarvoisesti konsoli käynnistyy 100 Hz:llä. Ja useimmat pelit käyttävät tätä taajuutta.

Pelin kehittäjä Andy asetti ajastimen 1 kHz:iin, jotta liikkeet laskettaisiin tarkemmin. Andylla on tapana mennä yli laidan, ja jos jäljittelemme painovoimaa, teemme sen mahdollisimman tarkasti!

Mutta entä jos ajastimen nopeuttaminen vaikuttaisi jotenkin ohjelman yleiseen ajoitukseen ja siten muistikortin tiedonsiirtonopeutta säätelevään kelloon?

Kommentoin ajastinkoodia. Virhe ei toistunut. Mutta tämä ei tarkoita, että korjasimme sen, koska vika tapahtui satunnaisesti. Entä jos olisin vain onnekas?

Muutamaa päivää myöhemmin kokeilin uudelleen testiohjelmaa. Vika ei toistunut. Palasin koko pelin koodikantaan ja muokkasin tallennus- ja latauskoodia niin, että ohjelmoitava ajastin nollautuisi alkuperäiseen arvoonsa (100 Hz) ennen muistikortin käyttöä ja nollautui sitten takaisin 1 kHz:iin. Ei tullut enempää törmäyksiä.

Mutta miksi tämä tapahtui?

Palasin taas testiohjelmaan. Yritin löytää kuvion 1 kHz ajastimen virheen esiintymisestä. Lopulta huomasin, että virhe ilmenee, kun joku pelaa PS1-ohjaimella. Koska teen tätä harvoin itse - miksi tarvitsisin ohjaimen, kun testaan ​​tallennus- ja latauskoodia? – En edes huomannut tätä riippuvuutta. Mutta eräänä päivänä eräs taiteilijoistamme odotti minun lopettavan testaamista - minä luultavasti kiroin sillä hetkellä - ja pyöritti hermostuneesti ohjainta käsissään. Tapahtui virhe. "Siis mitä?!" No, tee se uudestaan!"

Kun tajusin, että nämä kaksi tapahtumaa liittyvät toisiinsa, pystyin toistamaan virheen helposti: aloin tallentamisen muistikortille, siirsin ohjainta ja pilasin muistikortin. Minusta se näytti laitteistovialta.

Tulin Connien luo ja kerroin hänelle löydöstäni. Hän välitti tiedot yhdelle PS1:n suunnittelijoista. "Mahdotonta", hän vastasi, "Se ei voi olla laitteisto-ongelma." Pyysin Conniea järjestämään keskustelun.

Insinööri soitti minulle ja väittelimme hänen rikkinäisellä englannillaan ja (erittäin) rikkinäisellä japanillani. Lopulta sanoin: "Anna minun lähettää 30 rivin testiohjelma, jossa ohjaimen siirtäminen aiheuttaa virheen." Hän suostui. Sanoi, että se oli ajanhukkaa ja että hän oli hirveän kiireinen uuden projektin parissa, mutta antaisi periksi, koska olimme Sonylle erittäin tärkeä kehittäjä. Puhdistin testiohjelmani ja lähetin sen hänelle.

Seuraavana iltana (olimme Los Angelesissa ja hän Tokiossa) hän soitti minulle ja pyysi ikävästi anteeksi. Se oli laitteisto-ongelma.

En tiedä mikä vika tarkalleen ottaen oli, mutta Sonyn pääkonttorista kuulemani mukaan, jos ajastin asetti riittävän korkealle arvolle, se häiritsi emolevyn komponentteja ajastimen kristallin läheisyydessä. Yksi niistä oli muistikortin siirtonopeussäädin, joka myös asetti siirtonopeuden ohjaimille. En ole insinööri, joten saatoin sotkea jotain.

Mutta ydin on, että emolevyn komponenttien välillä oli häiriöitä. Ja kun dataa lähetettiin samanaikaisesti ohjainportin ja muistikorttiportin kautta 1 kHz:n ajastimella, bittejä katosi, tietoja katosi ja kortti vaurioitui.

Huonot lehmät

1980-luvulla mentorini Sergei kirjoitti ohjelmiston SM-1800:lle, PDP-11:n Neuvostoliiton kloonille. Tämä mikrotietokone on juuri asennettu rautatieasemalle lähellä Sverdlovskia, joka on tärkeä liikennekeskus Neuvostoliitossa. Uusi järjestelmä suunniteltiin vaunujen ja tavaraliikenteen reitittämiseen. Mutta se sisälsi ärsyttävän bugin, joka johti satunnaisiin kaatumisiin ja kaatumisiin. Kaatuminen tapahtui aina, kun joku meni kotiin illalla. Mutta seuraavan päivän perusteellisesta tutkimuksesta huolimatta tietokone toimi oikein kaikissa manuaalisissa ja automaattisissa testeissä. Tämä tarkoittaa yleensä kilpailutilannetta tai muuta kilpailuvirhettä, joka ilmenee tietyissä olosuhteissa. Myöhäisillan puheluihin kyllästynyt Sergei päätti perehtyä asian ytimeen ja ennen kaikkea ymmärtää, mitkä olosuhteet ratapihalla johtivat tietokoneen rikkoutumiseen.

Ensin hän keräsi tilastot kaikista selittämättömistä kaatumisista ja loi kaavion päivämäärän ja ajan mukaan. Malli oli selvä. Tarkkailtuaan vielä muutaman päivän Sergei tajusi, että hän pystyi helposti ennustamaan tulevien järjestelmävikojen ajan.

Pian hän sai tietää, että häiriöt ilmenivät vasta, kun asema lajitteli junakuormat karjaa Pohjois-Ukrainasta ja Länsi-Venäjältä suuntasi läheiseen teurastamoon. Tämä oli sinänsä outoa, koska teurastamo toimitti paljon lähempänä, Kazakstanissa sijaitsevilta tiloilta.

Tšernobylin ydinvoimala räjähti vuonna 1986, ja radioaktiiviset laskeumat tekivät ympäröivät alueet asumiskelvottomaksi. Laajat alueet Pohjois-Ukrainassa, Valko-Venäjällä ja Länsi-Venäjällä olivat saastuneet. Sergei epäili korkeaa säteilytasoa saapuvissa vaunuissa ja kehitti menetelmän tämän teorian testaamiseksi. Väestöllä kiellettiin annosmittareita, joten Sergei ilmoittautui useiden sotilaiden luo rautatieasemalle. Useiden vodkan juomien jälkeen hän onnistui vakuuttamaan sotilaan mittaamaan säteilytason yhdessä epäilyttävässä vaunussa. Kävi ilmi, että taso oli useita kertoja normaaliarvoja korkeampi.

Nauta ei ainoastaan ​​lähettänyt paljon säteilyä, vaan sen taso oli niin korkea, että se johti satunnaiseen bittien menettämiseen aseman vieressä olevassa rakennuksessa sijaitsevan SM-1800:n muistissa.

Neuvostoliitossa oli pulaa ruoasta, ja viranomaiset päättivät sekoittaa Tšernobylin lihaa maan muilta alueilta peräisin olevan lihan kanssa. Tämä mahdollisti radioaktiivisuuden yleisen tason alentamisen menettämättä arvokkaita resursseja. Saatuaan tietää tästä, Sergei täytti välittömästi muuttoasiakirjat. Ja tietokoneen kaatumiset pysähtyivät itsestään, kun säteilytaso laski ajan myötä.

Putkien läpi

Olipa kerran Movietech Solutions loi elokuvateattereihin ohjelmiston, joka on suunniteltu kirjanpitoon, lipunmyyntiin ja yleiseen hallintoon. Lippulaivasovelluksen DOS-versio oli melko suosittu pienten ja keskisuurten elokuvateatteriketjujen keskuudessa Pohjois-Amerikassa. Ei siis ole yllättävää, että kun Windows 95 -versio julkistettiin, integroitu uusimpiin kosketusnäyttöihin ja itsepalvelukioskiin ja varustettu kaikenlaisilla raportointityökaluilla, myös siitä tuli nopeasti suosittu. Useimmiten päivitys sujui ongelmitta. Paikallinen IT-henkilöstö asensi uusia laitteita, siirsi tietoja ja liiketoiminta jatkui. Paitsi silloin kun se ei kestänyt. Kun tämä tapahtui, yritys lähetti Jamesin, lempinimeltään "The Cleaner".

Vaikka lempinimi viittaa ilkeäseen tyyppiin, siivooja on vain yhdistelmä ohjaajaa, asentajaa ja huippuammattia. James vietti muutaman päivän asiakkaan sivustolla kokoamassa kaikkia komponentteja ja vietti sitten vielä pari päivää opettaen henkilökunnalle uuden järjestelmän käyttöä, ratkaista mahdolliset laitteisto-ongelmat ja auttanut ohjelmistoa sen alkuvaiheessa.

Siksi ei ole yllättävää, että näinä hektisinä aikoina James saapui toimistoon aamulla, ja ennen kuin hän ehti päästä pöytänsä ääreen, johtaja tervehti häntä tavallista enemmän kofeiinilla.

"Pelkään, että sinun täytyy mennä Annapolisiin, Nova Scotiaan, mahdollisimman pian." Heidän koko järjestelmänsä hajosi, ja työskenneltyämme yön insinöörien kanssa emme voi selvittää, mitä tapahtui. Näyttää siltä, ​​että verkko on epäonnistunut palvelimella. Mutta vasta sen jälkeen, kun järjestelmä oli ollut käynnissä useita minuutteja.

– Eivätkö he palanneet vanhaan järjestelmään? - James vastasi täysin vakavasti, vaikka henkisesti hän laajensi silmänsä hämmästyksestä.

— Aivan: heidän IT-asiantuntijansa "muutti prioriteetteja" ja päätti lähteä vanhan palvelimensa kanssa. James, he asensivat järjestelmän kuuteen paikkaan ja maksoivat vain premium-tuesta, ja heidän liiketoimintaansa hoidetaan nyt kuten 1950-luvulla.

James suoristui hieman.

- Se on toinen asia. Okei, aloitetaan.

Kun hän saapui Annapolikseen, hän löysi ensimmäisenä asiakkaan ensimmäisen teatterin, jossa oli ongelma. Lentokentällä otetussa kartassa kaikki näytti kunnolliselta, mutta halutun osoitteen ympäristö näytti epäilyttävältä. Ei ghetto, mutta muistuttaa film noiria. Kun James pysäköi keskustan reunakiveen, prostituoitu lähestyi häntä. Ottaen huomioon Annapoliksen koon, se oli todennäköisesti ainoa koko kaupungissa. Hänen ulkonäkönsä toi heti mieleen kuuluisan hahmon, joka tarjosi seksiä rahasta suurella näytöllä. Ei, ei Julia Robertsistä, vaan Jon Voightista [viittaus elokuvaan "Midnight Cowboy" - noin. kaista].

Lähetettyään prostituoidun matkaan James meni elokuvateatteriin. Ympäröivä alue oli parantunut, mutta se antoi silti ajetun vaikutelman. Ei sillä, että James olisi ollut liian huolissaan. Hän on käynyt kurjissa paikoissa ennenkin. Ja tämä oli Kanada, jossa jopa ryöstäjät ovat kohteliaita sanomaan "kiitos" lompakkosi ottamisen jälkeen.

Elokuvateatterin sivusisäänkäynti oli pimeässä kujassa. James käveli ovelle ja koputti. Pian se narisi ja avautui hieman.

- Oletko siivooja? - kuului käheä ääni sisältä.

- Kyllä, se olen minä... Tulin korjaamaan kaiken.

James käveli elokuvateatterin aulaan. Henkilökunnalla ei ilmeisesti ollut muuta vaihtoehtoa, joten he alkoivat jakaa paperilippuja vierailijoille. Tämä teki taloudellisesta raportoinnista vaikeaa, puhumattakaan mielenkiintoisista yksityiskohdista. Mutta henkilökunta tervehti Jamesia helpotuksesta ja vei hänet välittömästi palvelinhuoneeseen.

Ensi silmäyksellä kaikki oli hyvin. James kirjautui palvelimelle ja tarkisti tavalliset epäilyttävät paikat. Ei ongelmaa. James kuitenkin sulki palvelimen, vaihtoi verkkokortin ja peruutti järjestelmän. Hän aloitti työnsä välittömästi täysillä. Henkilökunta alkoi jälleen myydä lippuja.

James soitti Markille ja kertoi hänelle tilanteesta. Ei ole vaikea kuvitella, että James haluaisi pysyä paikalla ja katsoa, ​​tapahtuuko jotain odottamatonta. Hän meni alas portaita ja alkoi kysyä työntekijöiltä, ​​mitä tapahtui. Ilmeisesti järjestelmä on lakannut toimimasta. He sammuttivat ja käynnistivät sen, kaikki toimi. Mutta 10 minuutin kuluttua järjestelmä kaatui.

Juuri tällä hetkellä tapahtui jotain vastaavaa. Yhtäkkiä lippujärjestelmä alkoi heittää virheitä. Henkilökunta huokaisi ja tarttui paperilippuihin, ja James kiirehti palvelinhuoneeseen. Kaikki näytti hyvältä palvelimen kanssa.

Sitten yksi työntekijöistä astui sisään.

– Järjestelmä toimii taas.

James oli ymmällään, koska hän ei ollut tehnyt mitään. Tarkemmin sanottuna ei mitään, mikä saisi järjestelmän toimimaan. Hän kirjautui ulos, otti puhelimensa ja soitti yrityksensä tukinumeroon. Pian sama työntekijä tuli palvelinhuoneeseen.

- Järjestelmä ei toimi.

James vilkaisi palvelinta. Näytöllä tanssii mielenkiintoinen ja tuttu kuvio monivärisistä muodoista - kaoottisesti väänteleviä ja kietouttavia piippuja. Olemme kaikki nähneet tämän näytönsäästäjän jossain vaiheessa. Se oli kauniisti renderöity ja kirjaimellisesti hypnotisoiva.


James painoi nappia ja kuvio katosi. Hän kiirehti lipputoimistoon ja tapasi matkalla hänen luokseen palaavan työntekijän.

– Järjestelmä toimii taas.

Jos voit tehdä mentaalisen facepalmin, James teki juuri sen. Näytönsäästäjä. Se käyttää OpenGL:ää. Ja siksi se kuluttaa käytön aikana kaikki palvelinprosessorin resurssit. Tämän seurauksena jokainen puhelu palvelimelle päättyy aikakatkaisuun.

James palasi palvelinhuoneeseen, kirjautui sisään ja korvasi näytönsäästäjän kauniilla putkilla tyhjällä näytöllä. Eli 100 % prosessorin resursseista kuluttavan näytönsäästäjän sijaan asensin toisen, joka ei kuluta resursseja. Sitten odotin 10 minuuttia tarkistaakseni arvaukseni.

Kun James saapui seuraavaan elokuvateatteriin, hän pohti, kuinka selittää johtajalleen, että hän oli juuri lentänyt 800 km sammuttaakseen näytönsäästäjän.

Törmäys tietyn kuun vaiheen aikana

Tositarina. Eräänä päivänä ilmeni ohjelmistovirhe, joka riippui kuun vaiheesta. Siellä oli pieni rutiini, jota käytettiin yleisesti useissa MIT-ohjelmissa laskemaan Kuun todellisen vaiheen likiarvo. GLS rakensi tämän rutiinin LISP-ohjelmaksi, joka tulostaa tiedostoa kirjoitettaessa rivin, jonka aikaleima on lähes 80 merkkiä pitkä. Oli hyvin harvinaista, että viestin ensimmäinen rivi päätyi liian pitkäksi ja johti seuraavalle riville. Ja kun ohjelma myöhemmin luki tämän tiedoston, se kirosi. Ensimmäisen rivin pituus riippui tarkasta päivämäärästä ja kellonajasta sekä vaihemäärittelyn pituudesta aikaleiman tulostushetkellä. Eli vika kirjaimellisesti riippui kuun vaiheesta!

Ensimmäinen paperipainos Jargon tiedosto (Steele-1983) sisälsi esimerkin sellaisesta rivistä, joka johti kuvattuun virheeseen, mutta ladonta "korjasi" sen. Tätä on sittemmin kuvattu "kuuvaihevikaksi".

Ole kuitenkin varovainen oletusten kanssa. Muutama vuosi sitten CERNin (European Center for Nuclear Research) insinöörit kohtasivat virheitä suuressa elektroni-positronitörmäyttimessä tehdyissä kokeissa. Koska tietokoneet käsittelevät aktiivisesti tämän laitteen tuottamaa valtavaa datamäärää ennen kuin tulokset näyttävät tutkijoille, monet arvelivat, että ohjelmisto oli jotenkin herkkä kuun vaiheelle. Useat epätoivoiset insinöörit pääsivät totuuden pohjaan. Virhe johtui 27 km pitkän renkaan geometrian pienestä muutoksesta, joka johtui Maan muodonmuutoksesta Kuun kulun aikana! Tämä tarina on tullut fysiikan kansanperinteeseen nimellä "Newtonin kosto hiukkasfysiikalle" ja esimerkki yksinkertaisimpien ja vanhimpien fysiikan lakien ja edistyneimpien tieteellisten käsitteiden välisestä yhteydestä.

WC:n huuhtelu pysäyttää junan

Paras laitteistovika, josta olen koskaan kuullut, oli suurnopeusjunassa Ranskassa. Virhe johti junan hätäjarrutukseen, mutta vain jos kyydissä oli matkustajia. Jokaisessa tällaisessa tapauksessa juna poistettiin liikenteestä, tarkastettiin, mutta mitään ei löytynyt. Sitten hänet lähetettiin takaisin linjalle, ja hän pysähtyi välittömästi.

Yhdessä tarkastuksessa junassa matkustanut insinööri meni wc:hen. Pian hän huuhtoutui pois, BOOM! Hätäpysähdys.

Insinööri otti yhteyttä kuljettajaan ja kysyi:

– Mitä teit juuri ennen jarrutusta?

- No, hidastin vauhtia alaspäin...

Tämä oli outoa, sillä normaalin käytön aikana juna hidastaa alaslaskuissa kymmeniä kertoja. Juna jatkoi, ja seuraavassa laskussa kuljettaja varoitti:

- Aion hidastaa.

Mitään ei tapahtunut.

– Mitä teit viimeisen jarrutuksen aikana? - kysyi kuljettaja.

- No... olin wc:ssä...

- No, mene sitten wc:hen ja tee mitä teit, kun taas menemme alas!

Insinööri meni wc:hen, ja kun kuljettaja varoitti: ”Olen hidastunut”, hän huuhteli vettä. Tietenkin juna pysähtyi heti.

Nyt he pystyivät toistamaan ongelman, ja heidän oli löydettävä syy.

Kahden minuutin kuluttua he huomasivat, että moottorijarrun kauko-ohjaimen kaapeli (junassa oli yksi moottori kummassakin päässä) oli irti sähkökaapin seinästä ja makasi wc-pistokkeen solenoidia ohjaavalla releellä... Kun rele käynnistettiin, se aiheutti häiriöitä jarrukaapeliin, ja järjestelmän suojaus vikoja vastaan ​​sisälsi yksinkertaisesti hätäjarrutuksen.

Portti, joka vihasi FORTRANia

Muutama kuukausi sitten huomasimme, että verkkoyhteydet mantereella [tämä oli Havaijilla] olivat hidastumassa hyvin, hyvin hitaasti. Tämä voi kestää 10-15 minuuttia ja sitten yhtäkkiä toistua. Jonkin ajan kuluttua kollegani valitti minulle, että verkkoyhteydet mantereella yleensä ei toimi. Hänellä oli FORTRAN-koodia, joka piti kopioida mantereella olevalle koneelle, mutta se ei voinut, koska "verkko ei kestänyt tarpeeksi kauan FTP-latauksen suorittamiseksi."

Kyllä, kävi ilmi, että verkkohäiriöitä tapahtui, kun kollega yritti FTP-tiedostoa, jossa oli lähdekoodia FORTRANissa, mantereella olevalle koneelle. Yritimme arkistoida tiedoston: sitten se kopioitiin sujuvasti (mutta kohdekoneessa ei ollut pakkaajaa, joten ongelma ei ratkennut). Lopulta "halkaisimme" FORTRAN-koodin hyvin pieniksi paloiksi ja lähetimme ne yksi kerrallaan. Suurin osa fragmenteista kopioitiin ilman ongelmia, mutta muutama kappale ei mennyt läpi tai meni sen jälkeen useat yrityksiä.

Kun tutkimme ongelmallisia kohtia, havaitsimme, että niissä oli jotain yhteistä: ne kaikki sisälsivät kommenttilohkoja, jotka alkoivat ja päättyivät isolla C:llä koostuvilla riveillä (kollegani halusi kommentoida FORTRANissa). Lähetimme sähköpostia mantereen verkkoasiantuntijoille ja pyysimme apua. Tietenkin he halusivat nähdä näytteitä tiedostoistamme, joita ei voitu siirtää FTP:n kautta... mutta kirjeemme eivät saapuneet heille. Lopulta keksimme yksinkertaisen kuvatamiltä tiedostot, joita ei voi siirtää, näyttävät. Se toimi :) [Uskallanko lisätä tähän esimerkin yhdestä ongelmallisesta FORTRAN-kommentista? Ei ehkä sen arvoista!]

Lopulta saimme sen selville. Uusi yhdyskäytävä asennettiin äskettäin kampuksen osamme ja mantereen verkon välille. Sillä oli VALTAITA vaikeuksia lähettää paketteja, jotka sisälsivät toistuvia isoja C-bittejä! Vain muutamat näistä paketeista voivat viedä kaikki yhdyskäytävän resurssit ja estää useimpia muita paketteja pääsemästä läpi. Valitimme yhdyskäytävän valmistajalle... ja he vastasivat: "Voi, kyllä, kohtaat toistuvan C-virheen! Tiedämme jo hänestä." Lopulta ratkaisimme ongelman ostamalla uuden yhdyskäytävän toiselta valmistajalta (entisen puolustukseksi kyvyttömyys siirtää FORTRAN-ohjelmia voi olla etu joillekin!).

Kova aika

Muutama vuosi sitten, kun työskentelin ETL-järjestelmän luomisessa Perlissä vähentääkseni vaiheen 40 kliinisten tutkimusten kustannuksia, minun piti käsitellä noin 000 1 päivämäärää. Kaksi heistä ei läpäissyt koetta. Tämä ei häirinnyt minua liikaa, koska nämä päivämäärät otettiin asiakkaan toimittamista tiedoista, mikä oli usein, sanotaanko, yllättävää. Mutta kun tarkistin alkuperäiset tiedot, kävi ilmi, että nämä päivämäärät olivat 2011. tammikuuta 1 ja 2007. tammikuuta 30. Luulin, että vika oli juuri kirjoittamassani ohjelmassa, mutta kävi ilmi, että siitä on jo XNUMX vuotta. vanha. Tämä saattaa kuulostaa mystiseltä niille, jotka eivät tunne ohjelmistoekosysteemiä. Johtuen toisen yrityksen pitkäaikaisesta päätöksestä tehdä rahaa, asiakkaani maksoi minulle virheen korjaamisesta, jonka yksi yritys oli ottanut käyttöön vahingossa ja toinen tarkoituksella. Ymmärtääkseni, mistä puhun, minun on puhuttava yrityksestä, joka lisäsi ominaisuuden, josta tuli virhe, sekä muutamasta muusta mielenkiintoisesta tapahtumasta, jotka vaikuttivat korjaamaani salaperäiseen virheeseen.

Vanhoina hyvinä aikoina Applen tietokoneet asettivat toisinaan spontaanisti päivämääränsä 1. tammikuuta 1904. Syy oli yksinkertainen: se käytti paristokäyttöistä "järjestelmäkelloa" seuratakseen päivämäärää ja kellonaikaa. Mitä tapahtui kun akku loppui? Tietokoneet alkoivat seurata päivämäärää sekuntien lukumäärällä aikakauden alusta. Aikakaudella tarkoitimme alkuperäistä viitepäivämäärää, ja Macintosheille se oli 1. tammikuuta 1904. Ja pariston loppumisen jälkeen nykyinen päivämäärä palautettiin määritettyyn päivämäärään. Mutta miksi tämä tapahtui?

Aiemmin Apple käytti 32 bittiä tallentaakseen sekuntimäärän alkuperäisestä päivämäärästä. Yksi bitti voi tallentaa yhden kahdesta arvosta - 1 tai 0. Kaksi bittiä voi tallentaa yhden neljästä arvosta: 00, 01, 10, 11. Kolme bittiä - yksi arvo kahdeksasta: 000, 001, 010, 011, 100 , 101, 110, 111 jne. Ja 32 voisi tallentaa yhden 232 arvosta, eli 4 294 967 296 sekuntia. Applen päivämäärillä tämä vastasi noin 136 vuotta, joten vanhemmat Macit eivät pysty käsittelemään vuoden 2040 jälkeisiä päivämääriä. Ja jos järjestelmän akku tyhjenee, päivämäärä palautetaan 0 sekuntiin aikakauden alusta, ja sinun on asetettava päivämäärä manuaalisesti aina, kun käynnistät tietokoneen (tai kunnes ostat uuden akun).

Applen päätös tallentaa päivämäärät sekunteina aikakaudesta lähtien merkitsi kuitenkin sitä, että emme voineet käsitellä aikakautta edeltäviä päivämääriä, millä oli kauaskantoisia seurauksia, kuten tulemme näkemään. Apple esitteli ominaisuuden, ei vikaa. Tämä merkitsi muun muassa sitä, että Macintosh-käyttöjärjestelmä oli immuuni "millennium-bugille" (mitä ei voitu sanoa monista Mac-sovelluksista, joilla oli omat päivämääräjärjestelmänsä rajoitusten kiertämiseksi).

Mene eteenpäin. Käytimme Lotus 1-2-3:a, IBM:n "tappajasovellusta", joka auttoi käynnistämään PC-vallankumouksen, vaikka Applen tietokoneissa oli VisiCalc, joka teki henkilökohtaisesta tietokoneesta menestyksen. Rehellisesti sanottuna, jos 1-2-3 ei olisi ilmestynyt, tietokoneet tuskin olisivat nousseet, ja henkilökohtaisten tietokoneiden historia olisi voinut kehittyä hyvin eri tavalla. Lotus 1-2-3 käsitteli vuotta 1900 väärin karkausvuonna. Kun Microsoft julkaisi ensimmäisen laskentataulukkonsa, Multiplan, se valloitti pienen osan markkinoista. Ja kun he käynnistivät Excel-projektin, he päättivät paitsi kopioida rivien ja sarakkeiden nimeämisjärjestelmän Lotus 1-2-3:sta, myös varmistaa virheiden yhteensopivuuden käsittelemällä tarkoituksellisesti vuotta 1900 karkausvuonna. Tämä ongelma on edelleen olemassa. Eli 1-2-3:ssa tämä oli bugi, mutta Excelissä tietoinen päätös, joka varmisti, että kaikki 1-2-3 käyttäjät pystyivät tuomaan taulukonsa Exceliin muuttamatta tietoja, vaikka ne olisivat virheellisiä.

Mutta oli toinenkin ongelma. Ensin Microsoft julkaisi Excelin Macintoshille, joka ei tunnistanut päivämääriä ennen 1. tammikuuta 1904. Ja Excelissä 1. tammikuuta 1900 pidettiin aikakauden alussa. Siksi kehittäjät tekivät muutoksen niin, että heidän ohjelmansa tunnisti aikakauden tyypin ja tallensi tietoja itseensä halutun aikakauden mukaisesti. Microsoft jopa kirjoitti selittävän artikkelin tästä. Ja tämä päätös johti vikaani.

ETL-järjestelmäni vastaanotti asiakkailta Excel-laskentataulukoita, jotka oli luotu Windowsilla, mutta jotka voitiin luoda myös Macilla. Siksi aikakauden alku taulukossa voisi olla joko 1. tammikuuta 1900 tai 1. tammikuuta 1904. Kuinka selvittää? Excel-tiedostomuoto näyttää tarvittavat tiedot, mutta käyttämäni jäsentäjä ei näyttänyt niitä (nyt näyttää), ja oletti, että tiedät tietyn taulukon aikakauden. Olisin luultavasti voinut käyttää enemmän aikaa Excelin binaarimuodon ymmärtämiseen ja korjaustiedoston lähettämiseen jäsentimen tekijälle, mutta minulla oli paljon muutakin tehtävää asiakkaan hyväksi, joten kirjoitin nopeasti heuristiikan aikakauden määrittämiseksi. Hän oli yksinkertainen.

Excelissä päivämäärä 5 voidaan esittää muodossa "1998-07-05" (turha amerikkalainen järjestelmä), "98", "5", "98-5" tai jokin muu muoto, toinen hyödytön muoto (ironista kyllä, yksi muodoista, joita Excel-versioni ei tarjonnut, oli ISO 1998). Taulukossa muotoilematon päivämäärä tallennettiin kuitenkin joko "5" epookille 98 tai "8601" kaudelle 35981 (luvut edustavat päivien määrää aikakaudesta). Käytin yksinkertaisesti yksinkertaista jäsennintä poimiakseni vuoden muotoillusta päivämäärästä ja sitten Excelin jäsentimen avulla vuoden muotoilemattomasta päivämäärästä. Jos molemmat arvot erosivat 1900 vuotta, tiesin käyttäväni järjestelmää epoch-34519:n kanssa.

Miksi en vain käyttänyt muotoiltuja päivämääriä? Koska 5. heinäkuuta 1998 voidaan muotoilla "heinäkuuta 98" ja kuukauden päivä menetetään. Saimme taulukoita niin monilta yrityksiltä, ​​jotka loivat ne niin monella eri tavalla, että meidän (tässä tapauksessa minun) tehtävänä oli selvittää päivämäärät. Sitä paitsi, jos Excel saa sen oikein, niin meidänkin pitäisi!

Samaan aikaan törmäsin 39082:een. Muistutan, että Lotus 1-2-3 piti vuotta 1900 karkausvuonna, ja tämä toistettiin uskollisesti Excelissä. Ja koska tämä lisäsi yhden päivän vuoteen 1900, monet päivämäärän laskentafunktiot voivat olla väärässä juuri tuolle päivälle. Eli 39082 olisi voinut olla 1. tammikuuta 2011 (Macissa) tai 31. joulukuuta 2006 (Windowsissa). Jos "vuoden jäsentäjäni" poimi vuoden 2011 muotoillusta arvosta, kaikki on kunnossa. Mutta koska Excel-jäsennin ei tiedä, mitä aikakautta käytetään, sen oletusarvo on epoch-1900 ja palauttaa vuoden 2006. Sovellukseni näki eron olevan 5 vuotta, piti sitä virheenä, kirjasi sen ja palautti muotoilemattoman arvon.

Tämän kiertämiseksi kirjoitin tämän (pseudokoodi):

diff = formatted_year - parsed_year
if 0 == diff
    assume 1900 date system
if 4 == diff
    assume 1904 date system
if 5 == diff and month is December and day is 31
    assume 1904 date system

Ja sitten kaikki 40 000 päivämäärää jäsennettiin oikein.

Keskellä suuria tulostustöitä

1980-luvun alussa isäni työskenteli Storage Technologyssa, joka on nyt lakkautettu divisioona, joka loi nauha-asemia ja pneumaattisia järjestelmiä nopeaan nauhansyöttöön.

He suunnittelivat asemat uudelleen niin, että niissä voi olla yksi keskus "A"-asema kytkettynä seitsemään "B"-asemaan, ja pieni käyttöjärjestelmä RAM-muistissa, joka ohjasi "A"-asemaa, pystyi delegoimaan luku- ja kirjoitustoiminnot kaikille "B"-asemille.

Joka kerta kun A-asema käynnistettiin, levyke oli asetettava "A"-liitäntään yhdistettyyn oheisasemaan, jotta käyttöjärjestelmä ladataan sen muistiin. Se oli äärimmäisen alkeellista: laskentatehoa tarjosi 8-bittinen mikro-ohjain.

Tällaisten laitteiden kohdeyleisönä olivat yritykset, joilla on erittäin suuret tietovarastot - pankit, vähittäiskauppaketjut jne. - jotka joutuivat tulostamaan paljon osoitetarroja tai tiliotteita.

Yhdellä asiakkaalla oli ongelma. Keskellä tulostustyötä yksi tietty asema "A" saattaa lakata toimimasta, jolloin koko työ pysähtyy. Aseman toiminnan palauttamiseksi henkilöstön oli käynnistettävä kaikki uudelleen. Ja jos tämä tapahtui keskellä kuuden tunnin tehtävää, niin valtava määrä kallista tietokoneaikaa menetettiin ja koko operaation aikataulu häiriintyi.

Teknikot lähetettiin Storage Technologiesista. Parhaista yrityksistään huolimatta he eivät pystyneet toistamaan virhettä testiolosuhteissa: se näytti tapahtuvan keskellä suuria tulostustöitä. Ongelma ei ollut laitteistossa, he korvasivat kaiken, mitä pystyivät: RAM, mikrokontrolleri, levykeasema, kaikki mahdolliset nauha-aseman osat - ongelma jatkui.

Sitten teknikot soittivat päämajaan ja soittivat Asiantuntijalle.

Asiantuntija tarttui tuoliin ja kuppiin kahvia, istui tietokonehuoneessa – niinä päivinä oli tietokoneille omistettuja huoneita – ja katsoi, kuinka henkilökunta jonotti suuren painotyön. Asiantuntija odotti epäonnistumista - ja niin tapahtui. Kaikki katsoivat Asiantuntijaa, mutta hänellä ei ollut aavistustakaan, miksi näin tapahtui. Niinpä hän määräsi työn jonoon uudelleen, ja koko henkilökunta ja teknikot palasivat töihin.

Asiantuntija istuutui jälleen tuolille ja alkoi odottaa epäonnistumista. Kului noin kuusi tuntia ja vika tapahtui. Asiantuntijalla ei taaskaan ollut aavistustakaan, paitsi että kaikki tapahtui huoneessa, joka oli täynnä ihmisiä. Hän käski käynnistää tehtävän uudelleen, istuutui takaisin alas ja odotti.

Kolmannella epäonnistumisella asiantuntija huomasi jotain. Vika tapahtui, kun henkilökunta vaihtoi nauhaa vieraassa asemassa. Lisäksi vika tapahtui heti, kun yksi työntekijöistä käveli tietyn lattialla olevan laatan läpi.

Korotettu lattia tehtiin alumiinilaatoista, jotka oli asetettu 6-8 tuuman korkeuteen. Lukuisat tietokoneiden johdot kulkivat korotetun lattian alla, jotta kukaan ei vahingossa astu tärkeän kaapelin päälle. Laatat asetettiin erittäin tiukasti, jotta roskat eivät pääsisi korotetun lattian alle.

Asiantuntija huomasi, että yksi laatoista oli vääntynyt. Kun työntekijä astui sen nurkkaan, laatan reunat hankautuivat viereisiä laattoja vasten. Myös laattoja yhdistävät muoviosat hankautuivat, mikä aiheutti staattisia mikropurkauksia, jotka aiheuttivat radiotaajuisia häiriöitä.

Nykyään RAM on paljon paremmin suojattu radiotaajuushäiriöiltä. Mutta näinä vuosina näin ei ollut. Asiantuntija ymmärsi, että tämä häiriö häiritsi muistia ja sen myötä käyttöjärjestelmän toimintaa. Hän soitti tukipalveluun, tilasi uudet laatat, asensi ne itse ja ongelma poistui.

On nousuvesi!

Tarina tapahtui palvelinhuoneessa, Portsmouthin (luulen) toimiston neljännessä tai viidennessä kerroksessa, satama-alueella.

Eräänä päivänä Unix-palvelin päätietokannan kanssa kaatui. He käynnistivät hänet uudelleen, mutta hän jatkoi onnellisena putoamista yhä uudelleen ja uudelleen. Päätimme soittaa jollekin tukipalvelusta.

Tukimies... Luulen, että hänen nimensä oli Mark, mutta sillä ei ole väliä... En taida tuntea häntä. Ei sillä oikeastaan ​​väliä. Pysytään Markissa, okei? Loistava.

Joten muutaman tunnin kuluttua Mark saapui (ei ole pitkä matka Leedsistä Portsmouthiin, tiedäthän), käynnisti palvelimen ja kaikki toimi ilman ongelmia. Tyypillistä pirun tukea, asiakas suuttuu tästä kovasti. Mark tutkii lokitiedostoja eikä löydä mitään epämiellyttävää. Joten Mark nousee takaisin junaan (tai millä tahansa kulkuvälineellä, jolla hän saapui, se olisi voinut olla ontuva lehmä tietääkseni... joka tapauksessa, sillä ei ole väliä, okei?) ja lähtee takaisin Leedsiin tuhlattuaan päivä.

Samana iltana palvelin kaatuu uudelleen. Tarina on sama... palvelin ei nouse. Mark yrittää auttaa etänä, mutta asiakas ei voi käynnistää palvelinta.

Toinen juna, bussi, sitruunamarenki tai jotain muuta paskaa, ja Mark on taas Portsmouthissa. Katso, palvelin käynnistyy ilman ongelmia! Ihme. Mark viettää useita tunteja tarkistaakseen, että käyttöjärjestelmä tai ohjelmisto on kunnossa, ja lähtee Leedsiin.

Noin keskellä päivää palvelin kaatuu (ota rauhallisesti!). Tällä kertaa näyttää järkevältä tuoda laitteistotukihenkilöitä vaihtamaan palvelin. Mutta ei, noin 10 tunnin kuluttua se myös putoaa.

Tilanne toistui useita päiviä. Palvelin toimii, kaatuu noin 10 tunnin kuluttua eikä käynnisty seuraavien 2 tunnin aikana. He tarkastivat jäähdytystä, muistivuotoja, he tarkastivat kaiken, mutta eivät löytäneet mitään. Sitten törmäykset pysähtyivät.

Viikko meni huoletta... kaikki olivat onnellisia. Onnellista, kunnes kaikki alkaa uudestaan. Kuva on sama. 10 tuntia työtä, 2-3 tuntia seisokkia...

Ja sitten joku (luulen, että he kertoivat minulle, ettei tällä henkilöllä ollut mitään tekemistä IT:n kanssa) sanoi:

"Se on vuorovesi!"

Huudokseen kohdistettiin tyhjiä katseita, ja jonkun käsi luultavasti epäröi turvakutsupainiketta.

"Se lakkaa toimimasta vuoroveden mukana."

Tämä näyttäisi olevan täysin vieras käsite IT-tukityöntekijöille, jotka tuskin lukevat Tide Yearbookia kahville istuessaan. He selittivät, että tämä ei voinut liittyä vuoroveden millään tavalla, koska palvelin oli toiminut viikon ilman vikoja.

"Viime viikolla vuorovesi oli alhainen, mutta tällä viikolla se on korkea."

Hieman terminologiaa niille, joilla ei ole huvivenelupaa. Vuorovesi riippuu kuun kierrosta. Ja kun maa pyörii, Auringon ja Kuun vetovoima luo 12,5 tunnin välein hyökyaallon. 12,5 tunnin syklin alussa on nousuvesi, syklin puolivälissä laskuvesi ja lopussa taas nousuvesi. Mutta kun kuun kiertorata muuttuu, myös laskuveden ja nousuveden välinen ero muuttuu. Kun Kuu on Auringon ja Maan välissä tai Maan vastakkaisella puolella (täysikuu tai ei kuuta), saamme Syzygyn-vuoroveden - korkeimmat nousuvedet ja alhaisimmat laskuvedet. Puolikuun aikaan saamme kvadratuurivuorovesi - alimmat vuorovedet. Ero näiden kahden ääripään välillä pienenee huomattavasti. Kuusykli kestää 28 päivää: syzygian - kvadratuuri - syzygian - kvadratuuri.

Kun teknikoille selitettiin vuorovesivoimien olemus, he ajattelivat heti, että heidän oli kutsuttava poliisi. Ja ihan loogista. Mutta kävi ilmi, että kaveri oli oikeassa. Kaksi viikkoa aiemmin hävittäjä ankkuroitui lähellä toimistoa. Joka kerta kun vuorovesi nosti sen tietylle korkeudelle, aluksen tutkapylväs päätyi palvelinhuoneen lattian tasolle. Ja tutka (tai elektroniset sodankäyntilaitteet tai jokin muu sotilaallinen lelu) loi kaaoksen tietokoneisiin.

Raketin lentotehtävä

Minun tehtävänä oli siirtää suuri (noin 400 tuhatta riviä) raketin laukaisun ohjaus- ja valvontajärjestelmä käyttöjärjestelmän, kääntäjän ja kielen uusiin versioihin. Tarkemmin sanottuna Solaris 2.5.1:stä Solaris 7:ään ja Ada 83:lla kirjoitetusta Verdix Ada Development Systemistä (VADS) Ada 95:ssä kirjoitettuun Rational Apex Ada -järjestelmään. Rational osti VADS:n, ja sen tuote oli vanhentunut, vaikka Rational yritti ottaa käyttöön yhteensopivia versioita VADS-spesifisistä paketeista helpottaakseen siirtymistä Apex-kääntäjään.

Kolme ihmistä auttoi minua saamaan koodin puhtaaksi. Kesti kaksi viikkoa. Ja sitten työskentelin yksin saadakseni järjestelmän toimimaan. Lyhyesti sanottuna se oli pahin ohjelmistojärjestelmän arkkitehtuuri ja toteutus, jonka olin kohdannut, joten portin valmistuminen kesti vielä kaksi kuukautta. Järjestelmä lähetettiin sitten testattavaksi, mikä kesti vielä useita kuukausia. Korjasin heti testauksen aikana löydetyt bugit, mutta niiden määrä väheni nopeasti (lähdekoodina oli tuotantojärjestelmä, joten sen toiminnallisuus toimi varsin luotettavasti, jouduin vain poistamaan uuteen kääntäjään sopeutuessa ilmenneet bugit). Lopulta, kun kaikki toimi niin kuin pitääkin, minut siirrettiin toiseen projektiin.

Ja kiitospäivää edeltävänä perjantaina puhelin soi.

Raketin laukaisua oli tarkoitus testata noin kolmen viikon kuluttua, ja lähtölaskennan laboratoriotesteissä komentojen järjestys estyi. Tosielämässä tämä keskeyttäisi testin, ja jos tukos tapahtuisi muutaman sekunnin sisällä moottorin käynnistämisestä, apujärjestelmissä tapahtuisi useita peruuttamattomia toimia, jotka vaatisivat raketin pitkää - ja kallista - valmiutta. Se ei olisi alkanut, mutta monet ihmiset olisivat olleet hyvin järkyttyneitä ajan ja suuren rahan menetyksestä. Älä anna kenenkään kertoa sinulle, että puolustusministeriö käyttää rahaa holtittomasti – en ole koskaan tavannut sopimusjohtajaa, joka ei olisi asettanut budjettia ensimmäiseksi tai toiseksi ja sen jälkeen aikataulun.

Aikaisempina kuukausina tämä lähtölaskentahaaste oli ajettu satoja kertoja monissa muunnelmissa vain muutamalla pienellä hikkauksella. Joten tämän tapahtumisen todennäköisyys oli hyvin pieni, mutta sen seuraukset olivat erittäin merkittävät. Kerro nämä molemmat tekijät, niin ymmärrät, että uutiset ennustivat pilalla olevaa lomaviikkoa minulle ja kymmenille insinööreille ja johtajille.

Ja minuun kiinnitettiin huomiota henkilönä, joka siirsi järjestelmän.

Kuten useimmissa turvallisuuskriittisissä järjestelmissä, paljon parametreja kirjattiin lokiin, joten oli melko helppoa tunnistaa muutama koodirivi, jotka suoritettiin ennen järjestelmän kaatumista. Ja tietenkään niissä ei ollut mitään epätavallista; samat ilmaisut oli suoritettu onnistuneesti kirjaimellisesti tuhansia kertoja saman juoksun aikana.

Kutsuimme Apexin ihmiset Rationaliin, koska he kehittivät kääntäjän ja joitain heidän kehittämiään rutiineista kutsuttiin epäilyttävässä koodissa. Heihin (ja kaikkiin muihin) teki vaikutuksen se, että oli päästävä kirjaimellisesti kansallisesti tärkeän ongelman ytimeen.

Koska lehdissä ei ollut mitään mielenkiintoista, päätimme yrittää toistaa ongelman paikallisessa laboratoriossa. Tämä ei ollut helppo tehtävä, koska tapahtuma tapahtui noin kerran 1000 ajoa kohden. Yksi epäilty syy oli se, että kutsu toimittajan kehittämään mutex-toimintoon (osa VADS-siirtopakettia) Unlock ei johtanut lukituksen avaamiseen. Toimintoa kutsunut käsittelysäie käsitteli sydämenlyöntiviestejä, jotka saapuivat nimellisesti joka sekunti. Nostimme taajuuden 10 Hz:iin, eli 10 kertaa sekunnissa, ja aloimme juoksemaan. Noin tunnin kuluttua järjestelmä lukittui itsestään. Lokissa näimme, että tallennettujen viestien järjestys oli sama kuin epäonnistuneen testin aikana. Teimme useita ajoja lisää, järjestelmä oli jatkuvasti tukossa 45-90 minuuttia lähdön jälkeen ja joka kerta loki sisälsi saman reitin. Vaikka käytimme teknisesti eri koodia - viestitaajuus oli erilainen - järjestelmän käyttäytyminen oli sama, joten olimme varmoja, että tämä latausskenaario aiheutti saman ongelman.

Nyt meidän täytyi selvittää, missä esto tapahtui lausekkeiden sekvenssissä.

Tämä järjestelmän toteutus käytti Ada-tehtäväjärjestelmää ja käytti sitä uskomattoman huonosti. Tehtävät ovat Adassa korkean tason samanaikaisesti suoritettava rakennelma, kuten suoritussäikeitä, jotka on rakennettu vain itse kieleen. Kun kahden tehtävän täytyy olla yhteydessä toisiinsa, ne "soivat tapaamisen", vaihtavat tarvittavat tiedot ja lopettavat sitten tapaamisen ja palaavat itsenäiseen suoritukseensa. Järjestelmä toteutettiin kuitenkin toisin. Kun kohdetehtävä oli tapaamisen jälkeen, kohdetehtävä tapasi toisen tehtävän, joka sitten kohtasi kolmannen tehtävän ja niin edelleen, kunnes käsittely oli valmis. Tämän jälkeen kaikki tapaamiset saatiin päätökseen ja jokaisen tehtävän oli palattava suoritukseensa. Eli olimme tekemisissä maailman kalleimman toimintokutsujärjestelmän kanssa, joka pysäytti koko "multitasking"-prosessin samalla kun se käsitteli osan syöttötiedoista. Ja ennen tämä ei johtanut ongelmiin vain siksi, että läpijuoksu oli erittäin alhainen.

Kuvasin tätä tehtävämekanismia, koska kun tapaamista pyydettiin tai sen odotetaan valmistuvan, "tehtävän vaihto" voi tapahtua. Toisin sanoen prosessori voi aloittaa toisen tehtävän käsittelyn, joka on valmis suoritettavaksi. Osoittautuu, että kun yksi tehtävä on valmis kohtaamaan toisen tehtävän, täysin eri tehtävä voi alkaa suorittaa, ja lopulta ohjaus palaa ensimmäiseen tapaamiseen. Ja muita tapahtumia voi tapahtua, jotka saavat tehtävän vaihtamaan; yksi tällainen tapahtuma on kutsu järjestelmätoimintoon, kuten tulostaminen tai mutexin suorittaminen.

Ymmärtääkseni, mikä koodirivi aiheutti ongelman, minun piti löytää tapa tallentaa edistyminen lausesarjan läpi käynnistämättä tehtäväkytkintä, mikä estäisi kaatumisen. Joten en voinut hyödyntää sitä Put_Line()I/O-toimintojen suorittamisen välttämiseksi. Voisin asettaa laskurimuuttujan tai jotain vastaavaa, mutta miten voin nähdä sen arvon, jos en voi näyttää sitä näytöllä?

Lokia tarkasteltaessa kävi myös ilmi, että huolimatta sykeviestien käsittelyn jäätymisestä, joka esti kaikki prosessin I/O-toiminnot ja esti muun käsittelyn suorittamisen, muiden itsenäisten tehtävien suorittaminen jatkui. Eli työ ei ollut kokonaan tukossa, vain (kriittinen) tehtäväketju.

Tämä oli vihje, jota tarvittiin estävän lausekkeen arvioimiseen.

Tein Ada-paketin, joka sisälsi tehtävän, listatun tyypin ja kyseisen tyypin globaalin muuttujan. Lukemattomat literaalit sidottiin ongelmallisen sekvenssin tiettyihin ilmauksiin (esim. Incrementing_Buffer_Index, Locking_Mutex, Mutex_Unlocked), ja lisäsi sitten siihen kohdistuslausekkeita, jotka määrittivät vastaavan luettelon globaalille muuttujalle. Koska kaiken tämän objektikoodi yksinkertaisesti tallensi vakion muistiin, tehtävän vaihto sen suorittamisen seurauksena oli erittäin epätodennäköistä. Epäilimme ensisijaisesti ilmauksia, jotka voisivat vaihtaa tehtävää, koska esto tapahtui suorituksen yhteydessä sen sijaan, että se olisi palannut tehtävää vaihdettaessa (useista syistä).

Seurantatehtävä vain suoritettiin silmukassa ja tarkastettiin säännöllisesti nähdäkseen, oliko globaalin muuttujan arvo muuttunut. Jokaisen muutoksen yhteydessä arvo tallennettiin tiedostoon. Sitten lyhyt odotus ja uusi sekki. Kirjoitin muuttujan tiedostoon, koska tehtävä suoritettiin vasta, kun järjestelmä valitsi sen suoritettavaksi vaihdettaessa tehtävää ongelma-alueella. Mitä tahansa tässä tehtävässä tapahtui, se ei vaikuta muihin, toisiinsa liittymättömiin estettyihin tehtäviin.

Odotettiin, että kun järjestelmä saavutti ongelmallisen koodin suorittamisen, globaali muuttuja nollautuisi siirryttäessä jokaiseen seuraavaan lausekkeeseen. Sitten tapahtuu jotain, mikä saa tehtävän vaihtamaan, ja koska sen suoritustaajuus (10 Hz) on pienempi kuin valvontatehtävän, monitori voisi siepata globaalin muuttujan arvon ja kirjoittaa sen. Normaalissa tilanteessa voisin saada toistuvan sekvenssin luetteloiden osajoukosta: muuttujan viimeiset arvot tehtävän vaihdon hetkellä. Roikkuessa globaalin muuttujan ei pitäisi enää muuttua, ja viimeksi kirjoitettu arvo osoittaa, mikä lauseke ei ole valmis.

Ajoin koodin seurannan kanssa. Hän jäätyi. Ja valvonta toimi kuin kellonkello.

Loki sisälsi odotetun sekvenssin, jonka keskeytti arvo, joka osoitti, että mutex oli kutsuttu Unlock, ja tehtävää ei ole suoritettu loppuun - kuten tuhansien aikaisempien puhelujen tapauksessa.

Apexin insinöörit analysoivat tällä hetkellä kuumeisesti koodiaan ja löysivät mutexista paikan, jossa teoriassa voisi tapahtua lukko. Mutta sen todennäköisyys oli hyvin pieni, koska vain tietty tapahtumasarja tiettynä aikana saattoi johtaa tukkeutumiseen. Murphyn laki, kaverit, se on Murphyn laki.

Suojatakseni koodinpätkää, jota tarvitsen, korvasin mutex-funktiokutsut (rakennettu käyttöjärjestelmän mutex-toiminnallisuuden päälle) pienellä alkuperäisellä Ada mutex -paketilla ohjatakseni mutexin pääsyä kyseiseen osaan.

Lisäsin sen koodiin ja suoritin testin. Seitsemän tuntia myöhemmin koodi toimi edelleen.

Koodini lähetettiin Rationalille, jossa se käännettiin, purettiin ja tarkistettiin, ettei se käyttänyt samaa lähestymistapaa, jota käytettiin ongelmallisissa mutex-toiminnoissa.

Tämä oli urani ruuhkaisin koodiarvostelu 🙂 Huoneessani oli noin kymmenen insinööriä ja johtajaa, vielä kymmenen henkilöä oli puhelinkonferenssissa - ja he kaikki tutkivat noin 20 koodiriviä.

Koodi tarkistettiin, uudet suoritettavat tiedostot koottiin ja lähetettiin muodolliseen regressiotestaukseen. Pari viikkoa myöhemmin lähtölaskenta onnistui ja raketti lähti liikkeelle.

Okei, kaikki on hyvin, mutta mikä on tarinan pointti?

Se oli aivan inhottava ongelma. Satoja tuhansia koodirivejä, rinnakkainen suoritus, yli tusina vuorovaikutuksessa olevaa prosessia, huono arkkitehtuuri ja huono toteutus, sulautettujen järjestelmien rajapinnat ja miljoonia käytettyjä dollareita. Ei paineita, ei.

En ollut ainoa, joka työskenteli tämän ongelman parissa, vaikka olinkin valokeilassa siirrettäessä. Mutta vaikka tein sen, se ei tarkoita, että olisin ymmärtänyt kaikki sadat tuhannet koodirivit tai edes selannut niitä. Insinöörit eri puolilla maata analysoivat koodin ja lokit, mutta kun he kertoivat hypoteesinsa vian syistä, kesti vain puoli minuuttia niiden kumoamiseen. Ja kun minua pyydettiin analysoimaan teorioita, välitin sen jollekin muulle, koska minulle oli selvää, että nämä insinöörit menivät väärään suuntaan. Kuulostaako röyhkeältä? Kyllä, tämä on totta, mutta hylkäsin hypoteesit ja pyynnöt toisesta syystä.

Ymmärsin ongelman luonteen. En tiennyt tarkalleen missä se tapahtui tai miksi, mutta tiesin mitä tapahtui.

Vuosien varrella olen kerännyt paljon tietoa ja kokemusta. Olin yksi Adan käytön pioneereista ja ymmärsin sen edut ja haitat. Tiedän kuinka Adan ajonaikaiset kirjastot käsittelevät tehtäviä ja käsittelevät rinnakkaissuoritusta. Ja ymmärrän matalan tason ohjelmoinnin muistin, rekisterien ja assemblerin tasolla. Toisin sanoen minulla on syvä tietämys alaltani. Ja käytin niitä löytääkseni ongelman syyn. En vain kiertänyt vikaa, vaan ymmärsin kuinka löytää se erittäin herkässä ajonaikaisessa ympäristössä.

Tällaiset tarinat taistelusta koodin kanssa eivät ole kovin mielenkiintoisia niille, jotka eivät tunne tällaisen taistelun ominaisuuksia ja ehtoja. Mutta nämä tarinat auttavat meitä ymmärtämään, mitä todella vaikeiden ongelmien ratkaiseminen vaatii.

Ratkaistaksesi todella vaikeita ongelmia, sinun on oltava enemmän kuin pelkkä ohjelmoija. Sinun on ymmärrettävä koodin "kohtalo", kuinka se on vuorovaikutuksessa ympäristönsä kanssa ja kuinka ympäristö itse toimii.

Ja sitten sinulla on oma pilalla lomaviikkosi.

Jatkettava.

Lähde: will.com

Lisää kommentti