Folklora programerjev in inženirjev (1. del)

Folklora programerjev in inženirjev (1. del)

To je izbor zgodb iz interneta o tem, kako imajo hrošči včasih povsem neverjetne manifestacije. Morda imate tudi vi kaj povedati.

Avto alergija na vanilijev sladoled

Zgodba za inženirje, ki razumejo, da očitno ni vedno odgovor in da ne glede na to, kako napeta se zdijo dejstva, so še vedno dejstva. Oddelek Pontiac družbe General Motors Corporation je prejel pritožbo:

Pišem vam že drugič in ne zamerim vam, da ne odgovorite, ker se sliši noro. Naša družina ima tradicijo, da vsak večer po večerji jemo sladoled. Vrste sladoledov se vsakič menjajo, po večerji pa cela družina izbere, kateri sladoled bo kupila, nakar grem v trgovino. Pred kratkim sem kupil novega Pontiaca in od takrat so mi potovanja po sladoled postala problem. Vidite, vsakič, ko kupim vanilijev sladoled in se vrnem iz trgovine, avto noče vžgati. Če prinesem še kakšen sladoled, avto vžge brez problema. Želim postaviti resno vprašanje, ne glede na to, kako neumno se sliši: "Kaj je na Pontiacu, da se ne zažene, ko prinesem vaniljev sladoled, ampak se zlahka zažene, ko prinesem drug okus sladoleda?"

Kot si lahko predstavljate, je bil predsednik oddelka skeptičen glede pisma. Vendar sem za vsak slučaj poslal inženirja, da preveri. Presenečen je bil, da ga je srečal premožen, dobro izobražen moški, ki živi v lepem kraju. Dogovorila sta se, da se dobita takoj po večerji, da gresta oba v trgovino na sladoled. Tisti večer je bil vanilin in ko so se vrnili do avta, ta ni hotel vžgati.

Inženir je prišel še tri večere. Prvič je bil sladoled čokoladni. Avto je začel. Drugič je bil jagodni sladoled. Avto je začel. Tretji večer je prosil, naj vzame vanilijo. Avto ni vžgal.

Inženir je racionalno razmišljal in ni hotel verjeti, da je avto alergičen na vanilijev sladoled. Zato sem se z lastnikom avtomobila dogovoril, da bo z obiski nadaljeval, dokler ne najde rešitve problema. In spotoma si je začel delati zapiske: zapisoval si je vse podatke, uro dneva, vrsto bencina, uro prihoda in vrnitve iz trgovine itd.

Inženir je kmalu ugotovil, da lastnik avtomobila porabi manj časa za nakup vaniljevega sladoleda. Razlog je bila postavitev blaga v trgovini. Vanilijev sladoled je bil najbolj priljubljen in so ga hranili v ločenem zamrzovalniku na sprednji strani trgovine, da ga je bilo lažje najti. In vse druge sorte so bile v zadnjem delu trgovine in trajalo je veliko več časa, da smo našli pravo sorto in plačali.

Zdaj je bilo vprašanje za inženirja: zakaj avto ni vžgal, če je od trenutka, ko je bil motor ugasnjen, minilo manj časa? Ker je bil problem čas in ne vaniljev sladoled, je inženir hitro našel odgovor: bila je plinska ključavnica. Pojavljalo se je vsak večer, ko pa je lastnik avtomobila dlje časa iskal sladoled, se je motor uspel dovolj ohladiti in zlahka zagnati. In ko je moški kupil vanilijev sladoled, je bil motor še vedno prevroč in plinska ključavnica se ni imela časa raztopiti.

Morala: Celo popolnoma nore težave so včasih resnične.

Crash Bandicoot

Boleče je to doživeti. Kot programer se navadiš najprej kriviti svojo kodo, drugič, tretjič ... in nekje na desettisočem mestu kriviš prevajalnik. In nižje na seznamu že krivite opremo.

Tukaj je moja zgodba o napaki v strojni opremi.

Za igro Crash Bandicoot sem napisal kodo za nalaganje in shranjevanje na pomnilniško kartico. Za tako samozadovoljnega razvijalca iger je bilo to kot sprehod po parku: mislil sem, da bo delo trajalo več dni. Vendar sem na koncu odpravljal napake v kodi šest tednov. Spotoma sem reševal še druge težave, vendar sem se vsakih nekaj dni za nekaj ur vrnil k tej kodi. Bila je agonija.

Simptom je bil videti takole: ko shranite trenutno igranje igre in dostopate do pomnilniške kartice, gre skoraj vedno vse v redu ... Včasih pa časovna omejitev branja ali pisanja poteče brez očitnega razloga. Kratek posnetek pogosto poškoduje pomnilniško kartico. Ko igralec poskuša rešiti, ne samo, da ne reši, ampak tudi uniči zemljevid. Sranje.

Čez nekaj časa je našo producentko pri Sonyju Connie Bus zagrabila panika. Igre nismo mogli poslati s to napako in šest tednov kasneje nisem razumel, kaj povzroča težavo. Prek Connie smo stopili v stik z drugimi razvijalci PS1: je kdo naletel na kaj podobnega? št. Nihče ni imel težav s spominsko kartico.

Ko nimate idej za odpravljanje napak, je edini pristop, ki vam ostane, »razdeli in vladaj«: odstranite vedno več kode iz napačnega programa, dokler ne ostane relativno majhen delček, ki še vedno povzroča težavo. To pomeni, da program odrežete del za delom, dokler ne ostane del, ki vsebuje napako.

Toda stvar je v tem, da je zelo težko izrezati dele iz video igre. Kako ga zagnati, če ste odstranili kodo, ki posnema gravitacijo? Ali risanje likov?

Zato moramo cele module zamenjati s škrbinami, ki se pretvarjajo, da delajo nekaj koristnega, v resnici pa delajo nekaj zelo preprostega, kar ne more vsebovati napak. Takšne bergle moramo napisati, da igra vsaj deluje. To je počasen in boleč proces.

Skratka uspelo mi je. Odstranjeval sem vedno več delov kode, dokler mi ni ostala začetna koda, ki konfigurira sistem za zagon igre, inicializira strojno opremo za upodabljanje itd. Seveda na tej stopnji nisem mogel ustvariti menija za shranjevanje in nalaganje, ker bi moral ustvariti škrbino za vso grafično kodo. Lahko pa bi se pretvarjal, da sem uporabnik, ki uporablja (nevidni) zaslon za shranjevanje in nalaganje, ter zahteval shranjevanje in nato pisanje na pomnilniško kartico.

To mi je pustilo majhen košček kode, ki je še vedno imel zgornjo težavo - vendar se je še vedno dogajalo naključno! Najpogosteje je vse delovalo dobro, občasno pa je prišlo do napak. Odstranil sem skoraj vso kodo igre, vendar je hrošč še vedno živ. To je bilo zmedeno: preostala koda pravzaprav ni naredila ničesar.

V nekem trenutku, verjetno okoli treh zjutraj, se mi je utrnila misel. Operacije branja in pisanja (vnos/izhod) vključujejo natančne čase izvajanja. Ko delate s trdim diskom, pomnilniško kartico ali modulom Bluetooth, nizkonivojska koda, odgovorna za branje in pisanje, to počne v skladu z urnimi impulzi.

S pomočjo ure se naprava, ki ni neposredno povezana s procesorjem, sinhronizira s kodo, ki se izvaja na procesorju. Ura določa hitrost prenosa – hitrost prenosa podatkov. Če pride do zamenjave s časi, je tudi strojna ali programska oprema ali oboje. In to je zelo slabo, saj se lahko podatki poškodujejo.

Kaj pa, če nekaj v naši kodi zmede čase? Vse v zvezi s tem sem preveril v testni programski kodi in opazil, da smo programabilni časovnik v PS1 nastavili na 1 kHz (1000 taktov na sekundo). To je precej, privzeto, ko se konzola zažene, teče na 100 Hz. In večina iger uporablja to frekvenco.

Andy, razvijalec igre, je nastavil časovnik na 1 kHz, da bi se premiki izračunali natančneje. Andy ponavadi pretirava in če posnemamo gravitacijo, to naredimo kar se da natančno!

Toda kaj, če je pospešitev časovnika nekako vplivala na celotno časovno razporeditev programa in s tem na uro, ki uravnava hitrost prenosa za pomnilniško kartico?

Komentiral sem kodo časovnika. Napaka se ni ponovila. Vendar to ne pomeni, da smo ga popravili, saj je do napake prišlo naključno. Kaj če bi imel samo srečo?

Nekaj ​​dni kasneje sem ponovno eksperimentiral s testnim programom. Napaka se ni ponovila. Vrnil sem se k celotni kodni bazi igre in spremenil kodo za shranjevanje in nalaganje, tako da se je programabilni časovnik pred dostopom do pomnilniške kartice ponastavil na prvotno vrednost (100 Hz) in nato ponastavil nazaj na 1 kHz. Trkov ni bilo več.

Toda zakaj se je to zgodilo?

Ponovno sem se vrnil k testnemu programu. Poskušal sem najti nek vzorec v pojavu napake s časovnikom 1 kHz. Sčasoma sem opazil, da se napaka pojavi, ko nekdo igra s krmilnikom PS1. Ker bi to sam redko naredil - zakaj bi potreboval krmilnik pri testiranju kode za shranjevanje in nalaganje? - Te odvisnosti sploh nisem opazil. Nekega dne pa me je eden od naših umetnikov čakal, da končam s testiranjem - takrat sem verjetno preklinjal - in nervozno sukal krmilnik v rokah. Prišlo je do napake. "Počakaj, kaj?!" No, naredi še enkrat!"

Ko sem ugotovil, da sta ta dva dogodka medsebojno povezana, sem napako zlahka reproduciral: začel sem snemati na pomnilniško kartico, premaknil krmilnik in uničil pomnilniško kartico. Meni je bilo videti kot napaka v strojni opremi.

Prišel sem do Connie in ji povedal za svoje odkritje. Informacijo je posredovala enemu od inženirjev, ki so oblikovali PS1. "Nemogoče," je odgovoril, "ne more biti težava s strojno opremo." Prosil sem Connie, da nama organizira pogovor.

Inženir me je poklical in sva se prepirala v njegovi polomljeni angleščini in moji (skrajno) polomljeni japonščini. Na koncu sem rekel: "Naj pošljem svoj testni program s 30 vrsticami, kjer premikanje krmilnika povzroči napako." Strinjal se je. Rekel je, da je izguba časa in da je strašno zaposlen z novim projektom, vendar bo popustil, ker smo zelo pomemben razvijalec za Sony. Počistil sem svoj testni program in mu ga poslal.

Naslednji večer (mi smo bili v Los Angelesu, on pa v Tokiu) me je poklical in se sramežljivo opravičil. Težava je bila s strojno opremo.

Ne vem, kaj točno je bila napaka, toda glede na to, kar sem slišal na sedežu Sonyja, je, če nastavite časovnik na dovolj visoko vrednost, motil komponente na matični plošči v bližini kristala časovnika. Eden od njih je bil krmilnik hitrosti prenosa za pomnilniško kartico, ki je tudi nastavil hitrost prenosa za krmilnike. Nisem inženir, zato sem morda kaj zamočil.

Toda bistvo je, da je prišlo do motenj med komponentami na matični plošči. Pri hkratnem prenosu podatkov prek vrat krmilnika in vrat pomnilniške kartice s časovnikom, ki deluje pri 1 kHz, so bili izgubljeni biti, podatki so bili izgubljeni in kartica je bila poškodovana.

Slabe krave

V osemdesetih letih je moj mentor Sergej napisal programsko opremo za SM-1980, sovjetski klon PDP-1800. Ta mikroračunalnik je bil pravkar nameščen na železniški postaji blizu Sverdlovska, pomembnega prometnega vozlišča v ZSSR. Nov sistem je bil zasnovan za usmerjanje vagonov in tovornega prometa. Vendar je vseboval nadležno napako, ki je povzročila naključne zrušitve in zrušitve. Padci so se vedno zgodili, ko je kdo šel zvečer domov. Toda kljub temeljiti preiskavi naslednji dan je računalnik pri vseh ročnih in avtomatskih testih deloval pravilno. To običajno kaže na stanje dirke ali kakšno drugo tekmovalno napako, ki se pojavi pod določenimi pogoji. Utrujen od klicev pozno ponoči, se je Sergej odločil zadevi priti do bistva in najprej razumeti, kakšne razmere na ranžirni postaji so privedle do okvare računalnika.

Najprej je zbral statistiko vseh nepojasnjenih padcev in ustvaril graf po datumu in času. Vzorec je bil očiten. Potem ko je opazoval še nekaj dni, je Sergej ugotovil, da lahko zlahka predvidi čas prihodnjih okvar sistema.

Kmalu je izvedel, da je prišlo do motenj le, ko je postaja razvrščala vlake z govedom iz severne Ukrajine in zahodne Rusije v bližnjo klavnico. To je bilo samo po sebi nenavadno, saj so klavnico oskrbovale precej bližje farme, v Kazahstanu.

Černobilska jedrska elektrarna je eksplodirala leta 1986, zaradi radioaktivnih padavin pa so okoliška območja postala neprimerna za bivanje. Ogromna območja v severni Ukrajini, Belorusiji in zahodni Rusiji so bila onesnažena. Ker je sumil visoko raven sevanja v prihajajočih vagonih, je Sergej razvil metodo za preverjanje te teorije. Prebivalstvu je bilo prepovedano imeti dozimetre, zato se je Sergej prijavil pri več vojakih na železniški postaji. Po več pitjih vodke mu je uspelo prepričati vojaka, da je v enem od sumljivih vagonov izmeril stopnjo sevanja. Izkazalo se je, da je raven nekajkrat višja od običajnih vrednosti.

Ne samo, da je govedo oddajalo veliko sevanja, njegova raven je bila tako visoka, da je povzročila naključno izgubo bitov v pomnilniku SM-1800, ki se je nahajal v stavbi poleg postaje.

V ZSSR je primanjkovalo hrane in oblasti so se odločile mešati černobilsko meso z mesom iz drugih regij države. To je omogočilo zmanjšanje splošne ravni radioaktivnosti brez izgube dragocenih virov. Ko je izvedel za to, je Sergej takoj izpolnil dokumente za izselitev. In zrušitve računalnika so se ustavile same od sebe, ko se je raven sevanja sčasoma zmanjšala.

Skozi cevi

Nekoč je Movietech Solutions ustvaril programsko opremo za kinematografe, namenjeno računovodstvu, prodaji vstopnic in splošnemu upravljanju. Različica vodilne aplikacije za DOS je bila precej priljubljena med malimi in srednje velikimi verigami kinodvoran v Severni Ameriki. Zato ni presenetljivo, da je ob napovedi različice sistema Windows 95, integrirane z najnovejšimi zasloni na dotik in samopostrežnimi kioski ter opremljene z vsemi vrstami orodij za poročanje, hitro postala priljubljena. Najpogosteje je posodobitev potekala brez težav. Lokalni informatiki so namestili novo opremo, prenesli podatke in poslovanje se je nadaljevalo. Razen ko ni trajalo. Ko se je to zgodilo, je podjetje poslalo Jamesa z vzdevkom "Čistilec".

Čeprav vzdevek nakazuje zlobno vrsto, je čistilec le kombinacija inštruktorja, monterja in mojstra za vse obrti. James bi preživel nekaj dni na strankinem mestu, kjer je sestavljal vse komponente, nato pa preživel še nekaj dni, ko je učil osebje, kako uporabljati nov sistem, reševal morebitne težave s strojno opremo, ki so se pojavile, in v bistvu pomagal programski opremi v povojih.

Zato ne preseneča, da je v teh razburkanih časih James zjutraj prišel v pisarno in še preden je prišel do svoje mize, ga je pozdravil vodja, nabit s kofeinom nad običajno.

"Bojim se, da moraš čim prej v Annapolis, Nova Škotska." Njihov celoten sistem se je pokvaril in po noči dela z njihovimi inženirji ne moremo ugotoviti, kaj se je zgodilo. Videti je, da je omrežje na strežniku odpovedalo. A šele potem, ko je sistem deloval nekaj minut.

— Se niso vrnili v stari sistem? - James je odgovoril povsem resno, čeprav je v mislih presenečeno razširil oči.

— Točno: njihov informatik je »spremenil prioritete« in se odločil, da odide s starim strežnikom. James, so sistem namestili na šestih lokacijah in pravkar plačali za premium podporo, njihov posel pa zdaj poteka kot v petdesetih letih prejšnjega stoletja.

James se je rahlo vzravnal.

- To je druga stvar. V redu, začnimo.

Ko je prispel v Annapolis, je najprej našel strankino prvo gledališče, ki je imelo težave. Na zemljevidu, posnetem na letališču, je bilo vse videti spodobno, vendar je bilo območje okoli želenega naslova videti sumljivo. Ni geto, ampak spominja na film noir. Ko je James parkiral ob pločniku v središču mesta, se mu je približala prostitutka. Glede na velikost Annapolisa je bil najverjetneje edini v celotnem mestu. Njen videz je takoj spomnil na slavni lik, ki je na velikem platnu ponujal seks za denar. Ne, ne o Julii Roberts, ampak o Jonu Voightu [aluzija na film "Polnočni kavboj" - pribl. vozni pas].

Ko je poslal prostitutko na pot, je James odšel v kino. Okolica se je izboljšala, a je še vedno dajala vtis, da je uničena. Ne da bi bil James preveč zaskrbljen. Bil je že v nesrečnih krajih. In to je bila Kanada, kjer so tudi roparji dovolj vljudni, da vam rečejo "hvala", potem ko vam vzamejo denarnico.

Stranski vhod v kino je bil v vlažni ulici. James je stopil do vrat in potrkal. Kmalu je zaškripalo in se rahlo odprlo.

-Ste čistilka? - hripav glas je prišel od znotraj.

- Ja, jaz sem ... Prišel sem vse popraviti.

James je stopil v preddverje kina. Ker očitno ni imelo druge izbire, je osebje začelo obiskovalcem deliti papirnate vstopnice. To je otežilo finančno poročanje, kaj šele več zanimivih podrobnosti. Toda osebje je Jamesa pozdravilo z olajšanjem in ga takoj odpeljalo v strežniško sobo.

Na prvi pogled je bilo vse v redu. James se je prijavil v strežnik in preveril običajna sumljiva mesta. Brez težav. Vendar pa je James zaradi prevelike previdnosti zaustavil strežnik, zamenjal omrežno kartico in vrnil sistem nazaj. Takoj je začela delati na polno. Osebje je spet začelo prodajati vstopnice.

James je poklical Marka in ga obvestil o situaciji. Ni si težko predstavljati, da bi James morda želel ostati in videti, če se zgodi kaj nepričakovanega. Spustil se je po stopnicah in začel spraševati zaposlene, kaj se je zgodilo. Očitno je sistem prenehal delovati. Ugasnili so ga in prižgali, vse je delovalo. Toda po 10 minutah je sistem odpadel.

Ravno v tem trenutku se je zgodilo nekaj podobnega. Nenadoma je sistem izdajanja vozovnic začel kazati napake. Osebje je zavzdihnilo in zgrabilo papirnate vstopnice, James pa je pohitel v strežniško sobo. S strežnikom je bilo vse v redu.

Nato je vstopil eden od zaposlenih.

— Sistem spet deluje.

James je bil zmeden, ker ni naredil ničesar. Natančneje, nič takega, zaradi česar bi sistem deloval. Odjavil se je, vzel telefon in poklical podporo svojega podjetja. Kmalu je isti zaposleni vstopil v strežniško sobo.

- Sistem ne deluje.

James je pogledal strežnika. Zanimiv in poznan vzorec raznobarvnih oblik je plesal na zaslonu - kaotično zvijanje in prepletanje cevi. Vsi smo že kdaj videli ta ohranjevalnik zaslona. Bilo je čudovito upodobljeno in dobesedno hipnotizirajoče.


James je pritisnil gumb in vzorec je izginil. Pohitel je do blagajne in na poti srečal uslužbenca, ki se je vračal k njemu.

— Sistem spet deluje.

Če lahko naredite miselno obrazno dlan, je točno to naredil James. Ohranjevalnik zaslona. Uporablja OpenGL. In zato med delovanjem porabi vse vire strežniškega procesorja. Posledično se vsak klic strežnika konča s časovno omejitvijo.

James se je vrnil v strežniško sobo, se prijavil in zamenjal ohranjevalnik zaslona s čudovitimi cevmi s praznim zaslonom. To pomeni, da sem namesto ohranjevalnika zaslona, ​​ki porabi 100% virov procesorja, namestil drugega, ki ne porabi virov. Nato sem čakal 10 minut, da sem preveril svoje ugibanje.

Ko je James prišel v naslednji kino, se je spraševal, kako naj svojemu vodji razloži, da je ravnokar preletel 800 km, da bi izklopil ohranjevalnik zaslona.

Strmoglavljenje v določeni fazi lune

Resnična zgodba. Nekega dne se je pojavila programska napaka, ki je bila odvisna od lunine faze. Obstajala je majhna rutina, ki se je običajno uporabljala v različnih programih MIT za izračun približka pravi fazi Lune. GLS je to rutino vgradil v program LISP, ki bi pri pisanju datoteke izpisal vrstico s časovnim žigom, dolgim ​​skoraj 80 znakov. Zelo redko je bilo, da bi bila prva vrstica sporočila predolga in vodila do naslednje vrstice. In ko je program pozneje prebral to datoteko, je preklinjal. Dolžina prve vrstice je bila odvisna od točnega datuma in ure ter dolžine specifikacije faze v času, ko je bil natisnjen časovni žig. To pomeni, da je hrošč dobesedno odvisen od faze lune!

Prva papirnata izdaja Žargonska datoteka (Steele-1983) je vseboval primer takšne vrstice, ki je privedla do opisane napake, vendar jo je pisec "popravil". To je bilo od takrat opisano kot "napaka luninih faz".

Vendar bodite previdni pri predpostavkah. Pred nekaj leti so inženirji iz CERN-a (Evropskega centra za jedrske raziskave) naleteli na napake pri poskusih, izvedenih na velikem trkalniku elektronov in pozitronov. Ker računalniki aktivno obdelajo ogromno količino podatkov, ki jih ustvari ta naprava, preden rezultat pokažejo znanstvenikom, so mnogi ugibali, da je programska oprema nekako občutljiva na fazo lune. Nekaj ​​obupanih inženirjev je prišlo resnici do dna. Napaka je nastala zaradi rahle spremembe geometrije 27 km dolgega obroča zaradi deformacije Zemlje med prehodom Lune! Ta zgodba je vstopila v fizikalno folkloro kot »Newtonovo maščevanje fiziki delcev« in primer povezave med najpreprostejšimi in najstarejšimi zakoni fizike ter najnaprednejšimi znanstvenimi koncepti.

Splakovanje stranišča ustavi vlak

Najboljša napaka v strojni opremi, za katero sem kdaj slišal, je bila na hitrem vlaku v Franciji. Hrošč je povzročil zasilno zaviranje vlaka, a le, če so bili na njem potniki. V vsakem takem primeru so vlak izločili iz prometa, ga pregledali, vendar niso našli ničesar. Nato so ga poslali nazaj na linijo in takoj se je strmoglavil in ustavil.

Med eno od kontrol je strojnik, ki je potoval na vlaku, odšel na stranišče. Kmalu se je opral, BUM! Ustavitev v sili.

Inženir je stopil v stik z voznikom in vprašal:

— Kaj si počel tik pred zaviranjem?

- No, pri spustu sem upočasnil ...

To je bilo nenavadno, saj med normalnim delovanjem vlak na spustih upočasni več desetkrat. Vlak je peljal naprej in na naslednjem spustu je strojevodja opozoril:

- Upočasnil bom.

Se ni nič zgodilo.

— Kaj ste naredili med zadnjim zaviranjem? - je vprašal voznik.

- No ... Bil sem na stranišču ...

- No, potem pa pojdi na stranišče in počni to, kar si naredil, ko greva spet dol!

Inženir je šel na stranišče in ko ga je voznik opozoril: »Upočasnjujem,« je spustil vodo. Seveda se je vlak takoj ustavil.

Zdaj so lahko ponovili težavo in morali so najti vzrok.

Po dveh minutah so opazili, da je kabel za daljinsko upravljanje motorne zavore (vlak je imel po en motor na obeh koncih) odklopljen od stene električne omarice in leži na releju, ki je krmilil solenoid straniščne čepke ... Ko je rele je bil vklopljen, je povzročil motnje v zavornem kablu, sistemska zaščita pred okvarami pa je preprosto vključila zaviranje v sili.

Prehod, ki je sovražil FORTRAN

Pred nekaj meseci smo opazili, da postajajo omrežne povezave na celini [to je bilo na Havajih] zelo, zelo počasne. To lahko traja 10-15 minut in se nato nenadoma ponovi. Čez nekaj časa mi je kolega potožil, da so omrežne povezave na celini na splošno ne deluje. Imel je nekaj kode FORTRAN, ki jo je bilo treba kopirati na stroj na celini, vendar ni mogel, ker "omrežje ni zdržalo dovolj dolgo, da bi se nalaganje FTP končalo."

Da, izkazalo se je, da je prišlo do napak v omrežju, ko je kolega poskušal FTP poslati datoteko z izvorno kodo v FORTRAN-u na stroj na celini. Datoteko smo poskušali arhivirati: potem se je gladko kopirala (toda ciljni stroj ni imel razpakirnika, tako da težava ni bila rešena). Nazadnje smo "razdelili" kodo FORTRAN na zelo majhne koščke in jih poslali enega za drugim. Večina fragmentov je bila kopirana brez težav, nekaj kosov pa ni šlo ali pa je šlo kasneje številnih poskusi.

Ko smo pregledali problematične odlomke, smo ugotovili, da imajo nekaj skupnega: vsi so vsebovali bloke komentarjev, ki so se začeli in končali z vrsticami, sestavljenimi iz velikega C (kot je kolega raje komentiral v FORTRAN-u). Po e-pošti smo poslali strokovnjakom za omrežja na celini in prosili za pomoč. Seveda so želeli videti vzorce naših datotek, ki jih ni bilo mogoče prenesti preko FTP ... vendar naša pisma niso prišla do njih. Končno smo prišli do preprostega opisatikako izgledajo neprenosljive datoteke. Delovalo je :) [Ali si drznem tukaj dodati primer enega od problematičnih komentarjev FORTRAN? Verjetno ni vredno!]

Na koncu nam je uspelo ugotoviti. Nedavno je bil nameščen nov prehod med našim delom kampusa in celinskim omrežjem. Imel je VELIKO težave pri prenosu paketov, ki so vsebovali ponavljajoče se bitove velikih črk C! Samo nekaj teh paketov bi lahko prevzelo vse vire prehoda in preprečilo večini drugih paketov prehod. Pritožili smo se proizvajalcu prehoda ... in odgovorili so: "O, ja, soočeni ste z napako ponavljajočega se C! Zanj že vemo.” Težavo smo na koncu rešili z nakupom novega prehoda od drugega proizvajalca (v obrambo prvega, nezmožnost prenosa programov FORTRAN je lahko za nekatere prednost!).

Težki časi

Pred nekaj leti, ko sem delal na ustvarjanju sistema ETL v Perlu za zmanjšanje stroškov 40. faze kliničnih preskušanj, sem moral obdelati približno 000 datumov. Dva od njih nista opravila preizkusa. To me ni preveč motilo, ker so bili ti datumi vzeti iz podatkov, ki so jih posredovale stranke, kar je bilo pogosto, lahko rečemo, presenetljivo. Toda ko sem preveril prvotne podatke, se je izkazalo, da sta ta datuma 1. januar 2011 in 1. januar 2007. Mislil sem, da je hrošč v programu, ki sem ga pravkar napisal, a se je izkazalo, da je že 30 let star. Za tiste, ki niso seznanjeni z ekosistemom programske opreme, se to morda sliši skrivnostno. Zaradi dolgotrajne odločitve drugega podjetja, da bo služilo denar, mi je stranka plačala, da popravim napako, ki jo je eno podjetje uvedlo po naključju, drugo pa namerno. Da boste razumeli, o čem govorim, moram govoriti o podjetju, ki je dodalo funkcijo, ki je na koncu postala hrošč, ter nekaj drugih zanimivih dogodkov, ki so prispevali k skrivnostni napaki, ki sem jo odpravil.

V dobrih starih časih so Apple računalniki včasih spontano ponastavili svoj datum na 1. januar 1904. Razlog je bil preprost: za sledenje datumu in času je uporabljal "sistemsko uro" na baterije. Kaj se je zgodilo, ko se je baterija izpraznila? Računalniki so začeli slediti datumu po številu sekund od začetka epohe. Z epoho smo mislili na referenčni prvotni datum, za Macintoshe pa je bil to 1. januar 1904. Ko se je baterija izpraznila, je bil trenutni datum ponastavljen na določenega. Toda zakaj se je to zgodilo?

Prej je Apple uporabljal 32 bitov za shranjevanje števila sekund od prvotnega datuma. En bit lahko shrani eno od dveh vrednosti - 1 ali 0. Dva bita lahko shranita eno od štirih vrednosti: 00, 01, 10, 11. Trije biti - ena vrednost od osmih: 000, 001, 010, 011, 100 , 101, 110, 111 itd. In 32 bi lahko shranil eno od 232 vrednosti, to je 4 sekund. Za datume Apple je to pomenilo približno 294 let, zato starejši računalniki Mac ne morejo obravnavati datumov po letu 967. In če se sistemska baterija izprazni, se datum ponastavi na 296 sekund od začetka epohe in morate ročno nastaviti datum vsakič, ko vklopite računalnik (ali dokler ne kupite nove baterije).

Vendar pa je Applova odločitev, da shranjuje datume kot sekunde od epohe, pomenila, da ne moremo obdelati datumov pred epoho, kar je imelo daljnosežne posledice, kot bomo videli. Apple je predstavil funkcijo, ne hrošča. Med drugim je to pomenilo, da je bil operacijski sistem Macintosh imun na "hrošč tisočletja" (česar ne moremo reči za številne aplikacije Mac, ki so imele lastne datumske sisteme za izogibanje omejitvam).

Kar daj. Uporabili smo Lotus 1-2-3, IBM-ovo "ubijalsko aplikacijo", ki je pomagala sprožiti revolucijo osebnih računalnikov, čeprav so Apple računalniki imeli VisiCalc, zaradi katerega je bil osebni računalnik uspešen. Po pravici povedano, če se 1-2-3 ne bi pojavil, osebni računalniki skoraj ne bi vzleteli in zgodovina osebnih računalnikov bi se lahko razvila zelo drugače. Lotus 1-2-3 je leto 1900 napačno obravnaval kot prestopno leto. Ko je Microsoft izdal svojo prvo preglednico Multiplan, je zavzel majhen delež trga. In ko so zagnali projekt Excel, so se odločili ne samo kopirati shemo poimenovanja vrstic in stolpcev iz Lotusa 1-2-3, temveč tudi zagotoviti združljivost hroščev z namerno obravnavo leta 1900 kot prestopnega leta. Ta problem obstaja še danes. Se pravi, v 1-2-3 je bila to napaka, v Excelu pa je šlo za zavestno odločitev, ki je zagotovila, da so lahko vsi uporabniki 1-2-3 uvozili svoje tabele v Excel brez spreminjanja podatkov, tudi če so bili nepravilni.

Toda pojavila se je še ena težava. Najprej je Microsoft izdal Excel za Macintosh, ki ni prepoznaval datumov pred 1. januarjem 1904. In v Excelu je 1. januar 1900 štel za začetek dobe. Zato so razvijalci naredili spremembo, tako da je njihov program prepoznal vrsto ere in vase shranil podatke v skladu z želeno ero. Microsoft je celo napisal razlagalni članek o tem. In ta odločitev je povzročila mojo napako.

Moj sistem ETL je prejel Excelove preglednice od strank, ki so bile ustvarjene v sistemu Windows, vendar jih je bilo mogoče ustvariti tudi v računalniku Mac. Zato je lahko začetek dobe v tabeli 1. januar 1900 ali 1. januar 1904. Kako ugotoviti? Format datoteke Excel prikazuje potrebne informacije, vendar jih razčlenjevalnik, ki sem ga uporabil, ni prikazal (zdaj jih) in je domneval, da poznate epoho za določeno tabelo. Verjetno bi lahko porabil več časa za razumevanje Excelove binarne oblike in pošiljanje popravka avtorju razčlenjevalnika, vendar sem moral narediti veliko več za stranko, zato sem hitro napisal hevristiko za določitev epohe. Bila je preprosta.

V Excelu lahko datum 5. julij 1998 predstavimo v formatu "07-05-98" (neuporaben ameriški sistem), "5. julij 98", "5. julij 1998", "5-jul-98" oz. nek drug format, še en neuporaben format (ironično, eden od formatov, ki ga moja različica Excela ni ponujala, je bil ISO 8601). Vendar pa je bil v tabeli neformatirani datum shranjen kot "35981" za obdobje 1900 ali kot "34519" za obdobje 1904 (številke predstavljajo število dni od obdobja). Preprosto sem uporabil preprost razčlenjevalnik, da sem izvlekel leto iz formatiranega datuma, nato pa sem uporabil Excelov razčlenjevalnik, da sem izvlekel leto iz neoblikovanega datuma. Če sta se obe vrednosti razlikovali za 4 leta, sem vedel, da uporabljam sistem z epoho-1904.

Zakaj nisem uporabil samo oblikovanih datumov? Ker je 5. julij 1998 mogoče formatirati kot "julij 98" z izgubljenim dnevom v mesecu. Prejeli smo tabele od toliko podjetij, ki so jih ustvarila na toliko različnih načinov, da smo morali sami (v tem primeru jaz) ugotoviti datume. Poleg tega, če gre Excelu prav, bi morali tudi mi!

Istočasno sem naletel na 39082. Naj vas spomnim, da je Lotus 1-2-3 štel 1900 za prestopno leto in to je bilo zvesto ponovljeno v Excelu. In ker je to letu 1900 dodalo en dan, je lahko veliko funkcij za izračun datuma napačnih prav za ta dan. To pomeni, da bi 39082 lahko bil 1. januar 2011 (v računalnikih Mac) ali 31. december 2006 (v sistemu Windows). Če je moj "razčlenjevalnik let" iz oblikovane vrednosti izvlekel leto 2011, je vse v redu. Ker pa razčlenjevalnik Excela ne ve, katero obdobje je uporabljeno, privzeto nastavi na obdobje 1900 in vrne leto 2006. Moja aplikacija je videla, da je razlika 5 let, menila, da gre za napako, jo zabeležila in vrnila neformatirano vrednost.

Da bi se temu izognil, sem napisal to (psevdokoda):

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

In potem je bilo vseh 40 datumov pravilno razčlenjenih.

Sredi velikih tiskalnih opravil

V zgodnjih osemdesetih letih prejšnjega stoletja je moj oče delal v Storage Technology, zdaj že propadlem oddelku, ki je ustvarjal tračne enote in pnevmatske sisteme za hitro podajanje trakov.

Pogone so preoblikovali tako, da so lahko imeli en osrednji pogon »A«, povezan s sedmimi pogoni »B«, majhen OS v RAM-u, ki je nadzoroval pogon »A«, pa je lahko prenesel operacije branja in pisanja na vse pogone »B«.

Ob vsakem zagonu pogona »A« je bilo treba v periferni pogon, priključen na »A«, vstaviti disketo, da se operacijski sistem naloži v njegov pomnilnik. Bil je izjemno primitiven: računalniško moč je zagotavljal 8-bitni mikrokrmilnik.

Ciljna skupina za takšno opremo so bila podjetja z zelo velikimi podatkovnimi skladišči – banke, trgovske verige itd. – ki so morala natisniti veliko naslovnih nalepk ali bančnih izpiskov.

Ena stranka je imela težavo. Sredi tiskalnega posla lahko en določen pogon »A« preneha delovati, zaradi česar se celotno opravilo ustavi. Za ponovno vzpostavitev delovanja pogona je moralo osebje znova zagnati vse. In če se je to zgodilo sredi šesturne naloge, je bilo izgubljeno ogromno dragega računalniškega časa in moten je bil urnik celotne operacije.

Tehnike so poslali iz podjetja Storage Technologies. Toda kljub vsem prizadevanjem jim napake ni uspelo reproducirati v testnih pogojih: zdelo se je, da se je pojavila sredi velikih tiskalnih opravil. Težava ni bila strojna oprema, zamenjali so vse, kar so lahko: RAM, mikrokrmilnik, disketno enoto, vse možne dele tračne enote - težava je vztrajala.

Nato so tehniki poklicali štab in poklicali Strokovnjaka.

Strokovnjak je zgrabil stol in skodelico kave, se usedel v računalniško sobo – v tistih časih so bile sobe, namenjene računalnikom – in opazoval, kako osebje postavlja v vrsto veliko tiskarsko opravilo. Izvedenec je čakal, da pride do okvare - in se je. Vsi so pogledali Strokovnjaka, a njemu ni bilo jasno, zakaj se je to zgodilo. Zato je ukazal, naj se delo znova postavi v čakalno vrsto, vse osebje in tehniki pa so se vrnili na delo.

Strokovnjak se je spet usedel na stol in začel čakati na neuspeh. Minilo je približno šest ur in prišlo je do okvare. Strokovnjak spet ni imel nobenih idej, razen tega, da se je vse zgodilo v sobi, polni ljudi. Ukazal je ponoven začetek misije, se usedel in čakal.

Pri tretji napaki je strokovnjak nekaj opazil. Do napake je prišlo, ko je osebje zamenjalo trakove v tujem pogonu. Še več, do okvare je prišlo takoj, ko je eden od zaposlenih stopil skozi določeno ploščico na tleh.

Dvignjena tla so bila izdelana iz aluminijastih ploščic, položenih v višini 6 do 8 palcev. Pod dvižnim podom so bile speljane številne žice iz računalnikov, da kdo ne bi pomotoma stopil na pomemben kabel. Ploščice so bile položene zelo tesno, da preprečijo, da bi smeti prišle pod dvignjena tla.

Izvedenec je ugotovil, da je ena od ploščic deformirana. Ko je zaposleni stopil na njen vogal, so se robovi ploščice drgnili ob sosednje ploščice. Z njimi so se drgnili tudi plastični deli, ki so povezovali ploščice, kar je povzročalo statične mikrorazelektritve, ki so ustvarjale radiofrekvenčne motnje.

Danes je RAM veliko bolje zaščiten pred radiofrekvenčnimi motnjami. A v tistih letih temu ni bilo tako. Strokovnjak je ugotovil, da je ta poseg motil spomin in s tem delovanje operacijskega sistema. Poklical je službo za podporo, naročil nove ploščice, jih namestil sam in težava je izginila.

Plima je!

Zgodba se je odvijala v strežniški sobi, v četrtem ali petem nadstropju pisarne v Portsmouthu (mislim), na območju dokov.

Nekega dne se je strežnik Unix z glavno bazo podatkov zrušil. Ponovno so ga zagnali, a je veselo vedno znova padal. Odločili smo se, da pokličemo nekoga iz podporne službe.

Tip za podporo... Mislim, da mu je bilo ime Mark, ampak to ni pomembno... Mislim, da ga ne poznam. Ni važno, res. Ostanimo pri Marku, prav? Super.

Tako je čez nekaj ur prišel Mark (od Leedsa do Portsmoutha ni dolga pot, veš), vklopil strežnik in vse je delovalo brez težav. Tipična prekleta podpora, stranka se zaradi tega zelo razburi. Mark pregleda dnevniške datoteke in ne najde nič slabega. Tako se Mark vrne na vlak (ali na katero koli prevozno sredstvo, s katerim je prispel, kolikor vem, bi lahko bila šepava krava ... kakorkoli, ni pomembno, v redu?) in se odpravi nazaj v Leeds, ko je zapravil dan.

Isti večer se strežnik znova zruši. Zgodba je ista...strežnik se ne dvigne. Mark poskuša pomagati na daljavo, vendar odjemalec ne more zagnati strežnika.

Še en vlak, avtobus, limonina meringa ali kakšna druga bedarija in Mark je spet v Portsmouthu. Poglejte, strežnik se zažene brez težav! Čudež. Mark več ur preveri, ali je z operacijskim sistemom ali programsko opremo vse v redu, in se odpravi v Leeds.

Približno sredi dneva se strežnik zruši (pomiri se!). Tokrat se zdi smiselno privabiti ljudi za podporo strojne opreme, ki bodo zamenjali strežnik. Ampak ne, po cca 10 urah tudi pade.

Situacija se je ponavljala nekaj dni. Strežnik dela, sesuje po cca 10 urah in se ne zažene še naslednji 2 uri. Preverili so hlajenje, puščanje spomina, vse so pregledali, a niso našli ničesar. Potem so se zrušitve ustavile.

Teden je minil brezskrbno... vsi veseli. Srečno, dokler se vse ne začne znova. Slika je ista. 10 ur dela, 2-3 ure mirovanja...

In potem je nekdo (mislim, da so mi rekli, da ta oseba nima nič z IT-jem) rekel:

"To je plima!"

Vzklik je bil sprejet s praznimi pogledi in nekdo je verjetno okleval pri gumbu za varnostni klic.

"S plimovanjem preneha delovati."

Zdi se, da je to povsem tuj koncept za delavce v podpori IT, ki verjetno ne bodo brali Tide Yearbooka, medtem ko sedijo na kavi. Pojasnili so, da to nikakor ne more biti povezano s plimovanjem, saj je strežnik deloval teden dni brez okvar.

"Prejšnji teden je bila plima nizka, ta teden pa je visoka."

Malo terminologije za tiste, ki nimate dovoljenja za jahto. Plimovanje je odvisno od luninega cikla. In ko se Zemlja vrti, vsakih 12,5 ur gravitacijska sila Sonca in Lune ustvari plimski val. Na začetku 12,5-urnega cikla je plima, sredi cikla oseka, na koncu pa spet plima. Toda s spreminjanjem lunine orbite se spreminja tudi razlika med plimo in oseko. Ko je Luna med Soncem in Zemljo ali na nasprotni strani Zemlje (polna luna ali brez lune), dobimo Syzygyn plimo – najvišjo plimo in najnižjo oseko. Ob polmesecu dobimo kvadraturne plime – najnižje plime. Razlika med obema skrajnostma se močno zmanjša. Lunin cikel traja 28 dni: sizigij - kvadratura - sizigij - kvadratura.

Ko so tehnikom pojasnili bistvo plimskih sil, so takoj pomislili, da morajo poklicati policijo. In precej logično. Vendar se je izkazalo, da je imel tip prav. Dva tedna prej je nedaleč od pisarne pristal rušilec. Vsakič, ko jo je plima dvignila na določeno višino, je ladijska radarska postaja končala na ravni tal strežniške sobe. In radar (ali oprema za elektronsko bojevanje ali kakšna druga vojaška igrača) je povzročil kaos v računalnikih.

Letalska misija za raketo

Zadolžen sem bil za prenos velikega (približno 400 tisoč vrstic) sistema za nadzor in nadzor izstrelitve raket na nove različice operacijskega sistema, prevajalnika in jezika. Natančneje, od Solarisa 2.5.1 do Solarisa 7 in od Verdix Ada Development System (VADS), napisanega v Adi 83, do sistema Rational Apex Ada, napisanega v Adi 95. VADS je kupil Rational, njegov izdelek pa je zastarel, čeprav je Rational poskušal implementirati združljive različice paketov, specifičnih za VADS, da bi olajšal prehod na prevajalnik Apex.

Trije ljudje so mi pomagali, da sem kodo čisto prevedel. Trajalo je dva tedna. In potem sem delal sam, da je sistem deloval. Skratka, to je bila najslabša arhitektura in izvedba programskega sistema, kar sem jih srečal, zato je trajalo še dva meseca, da smo dokončali prenos. Sistem je bil nato poslan v testiranje, ki je trajalo še nekaj mesecev. Napake, ki so bile ugotovljene med testiranjem, sem takoj popravil, vendar se je njihovo število hitro zmanjšalo (izvorna koda je bila produkcijski sistem, zato je njegova funkcionalnost delovala dokaj zanesljivo, odstraniti sem moral le napake, ki so nastale ob prilagajanju na nov prevajalnik). Na koncu, ko je vse delovalo kot mora, so me premestili na drug projekt.

In v petek pred zahvalnim dnevom je zazvonil telefon.

Izstrelitev rakete naj bi preizkusili v približno treh tednih, med laboratorijskimi preizkusi odštevanja pa je prišlo do blokade zaporedja ukazov. V resničnem življenju bi to prekinilo test in če bi do blokade prišlo v nekaj sekundah po zagonu motorja, bi se v pomožnih sistemih pojavilo več nepopravljivih dejanj, ki bi zahtevala dolgo - in drago - pripravljenost rakete. Ne bi se začelo, vendar bi bilo veliko ljudi zelo razburjenih zaradi izgube časa in veliko, veliko denarja. Naj vam kdo ne pove, da obrambno ministrstvo nepremišljeno porablja denar – nikoli nisem srečal pogodbenega vodje, ki proračuna ne bi postavil na prvo ali drugo mesto, nato pa na urnik.

V prejšnjih mesecih je bil ta izziv z odštevanjem izveden na stotine krat v številnih različicah, z le nekaj manjšimi zastoji. Torej je bila verjetnost, da se bo to zgodilo, zelo majhna, vendar so bile njegove posledice zelo pomembne. Pomnožite oba dejavnika in razumeli boste, da so novice napovedovale uničen počitniški teden zame ter na desetine inženirjev in menedžerjev.

In pozornost je bila namenjena meni kot osebi, ki je prenesla sistem.

Kot pri večini varnostno kritičnih sistemov je bilo tudi tukaj zabeleženih veliko parametrov, zato je bilo dokaj enostavno prepoznati nekaj vrstic kode, ki so bile izvedene, preden se je sistem zrušil. In seveda na njih ni bilo prav nič nenavadnega; isti izrazi so bili med isto vožnjo uspešno izvedeni dobesedno tisočkrat.

V Rational smo poklicali ljudi iz Apexa, ker so oni razvili prevajalnik in nekatere rutine, ki so jih razvili, so bile poklicane v sumljivi kodi. Nanje (in vse ostale) je naredil vtis, da je treba priti do korenine problema dobesedno nacionalnega pomena.

Ker v dnevnikih ni bilo nič zanimivega, smo se odločili, da poskusimo problem ponoviti v lokalnem laboratoriju. To ni bila lahka naloga, saj se je dogodek zgodil približno enkrat na 1000 izvajanj. Eden domnevnih razlogov je bil, da je klic funkcije mutex, ki jo je razvil prodajalec (del paketa za migracijo VADS) Unlock ni privedlo do odklepanja. Obdelovalna nit, ki je poklicala funkcijo, je obdelala sporočila srčnega utripa, ki so nominalno prispela vsako sekundo. Frekvenco smo dvignili na 10 Hz, torej 10-krat na sekundo, in začeli teči. Približno uro kasneje se je sistem sam zaklenil. V dnevniku smo videli, da je zaporedje posnetih sporočil enako kot pri neuspelem testu. Naredili smo še nekaj voženj, sistem je bil dosledno blokiran 45-90 minut po startu in vsakič je dnevnik vseboval isto pot. Čeprav smo tehnično izvajali drugačno kodo – pogostost sporočil je bila drugačna – je bilo vedenje sistema enako, zato smo bili prepričani, da ta scenarij obremenitve povzroča isto težavo.

Zdaj smo morali ugotoviti, kje točno je prišlo do blokiranja v zaporedju izrazov.

Ta izvedba sistema je uporabljala sistem opravil Ada in ga uporabljala neverjetno slabo. Naloge so visokonivojski sočasno izvedljiv konstrukt v Adi, nekaj podobnega izvajalnim nitim, ki so vgrajene le v sam jezik. Ko morata dve nalogi komunicirati, "postavita srečanje", izmenjata potrebne podatke, nato prekineta srečanje in se vrneta k neodvisnim izvedbam. Vendar je bil sistem implementiran drugače. Po srečanju ciljnega opravila se je to ciljno opravilo srečalo z drugim opravilom, ki se je nato srečalo s tretjim opravilom in tako naprej, dokler ni bila dokončana določena obdelava. Po tem so bila vsa ta srečanja zaključena in vsaka naloga se je morala vrniti k svoji izvedbi. Opravka smo imeli torej z najdražjim sistemom za klicanje funkcij na svetu, ki je med obdelavo dela vhodnih podatkov zaustavil celoten »večopravilni« proces. In prej to ni povzročalo težav samo zato, ker je bila prepustnost zelo nizka.

Ta mehanizem opravila sem opisal, ker bi lahko prišlo do "preklopa opravila", ko je bilo zahtevano ali pričakovano dokončanje srečanja. To pomeni, da bi lahko procesor začel obdelovati drugo nalogo, ki je pripravljena za izvedbo. Izkazalo se je, da ko je ena naloga pripravljena na srečanje z drugo nalogo, se lahko začne izvajati popolnoma drugačna naloga in sčasoma se nadzor vrne k prvemu srečanju. Lahko se zgodijo tudi drugi dogodki, ki povzročijo preklop opravila; en tak dogodek je klic sistemske funkcije, kot je tiskanje ali izvajanje muteksa.

Da bi razumel, katera vrstica kode je povzročala težavo, sem moral najti način za beleženje napredka skozi zaporedje stavkov, ne da bi sprožil preklop opravila, kar bi preprečilo zrušitev. Tako da nisem mogel izkoristiti Put_Line()da se izognete izvajanju V/I operacij. Lahko bi nastavil spremenljivko števca ali kaj podobnega, ampak kako naj vidim njeno vrednost, če je ne morem prikazati na zaslonu?

Prav tako se je ob pregledu dnevnika izkazalo, da so se kljub zamrznitvi obdelave srčnih sporočil, ki je blokirala vse V/I operacije procesa in onemogočala izvajanje drugih obdelav, še naprej izvajale druge neodvisne naloge. To pomeni, da delo ni bilo blokirano v celoti, le (kritična) veriga nalog.

To je bil namig, potreben za ovrednotenje blokirnega izraza.

Naredil sem paket Ada, ki je vseboval nalogo, oštevilčen tip in globalno spremenljivko tega tipa. Številni literali so bili vezani na specifične izraze problematičnega zaporedja (npr. Incrementing_Buffer_Index, Locking_Mutex, Mutex_Unlocked), nato pa vanj vstavil izraze za dodelitev, ki so dodelili ustrezno oštevilčenje globalni spremenljivki. Ker je objektna koda vsega tega preprosto shranila konstanto v pomnilnik, je bilo preklapljanje med opravili zaradi njenega izvajanja zelo malo verjetno. Sumničavi smo bili predvsem glede izrazov, ki bi lahko preklopili nalogo, saj je do blokade prišlo ob izvedbi, namesto da bi se vrnila ob preklopu naloge nazaj (iz več razlogov).

Naloga sledenja je preprosto potekala v zanki in občasno preverjala, ali se je vrednost globalne spremenljivke spremenila. Z vsako spremembo se je vrednost shranila v datoteko. Nato kratko čakanje in nov pregled. Spremenljivko sem zapisal v datoteko, ker je bila naloga izvedena le, ko jo je sistem izbral za izvedbo ob preklopu naloge v problemskem območju. Karkoli se zgodi v tem opravilu, ne bo vplivalo na druga, nepovezana blokirana opravila.

Pričakovano je bilo, da bo globalna spremenljivka ob prehodu na vsak naslednji izraz, ko bo sistem dosegel točko izvajanja problematične kode, ponastavljena. Nato se zgodi nekaj, kar povzroči preklop naloge, in ker je frekvenca izvajanja (10 Hz) nižja od frekvence nadzorne naloge, bi monitor lahko zajel vrednost globalne spremenljivke in jo zapisal. V običajni situaciji bi lahko dobil ponavljajoče se zaporedje podnabora oštevilčenj: zadnje vrednosti spremenljivke v času preklopa naloge. Pri obešenju se globalna spremenljivka ne bi smela več spreminjati, zadnja zapisana vrednost pa bo pokazala, kateri izraz ni bil dokončan.

Zagnal sem kodo s sledenjem. Zmrznil je. In spremljanje je delovalo kot ura.

Dnevnik je vseboval pričakovano zaporedje, ki ga je prekinila vrednost, ki kaže, da je bil poklican mutex Unlock, naloga pa ni dokončana – tako kot pri tisočih prejšnjih klicih.

Apexovi inženirji so v tem času mrzlično analizirali svojo kodo in našli mesto v mutexu, kjer bi teoretično lahko prišlo do zaklepanja. Toda njegova verjetnost je bila zelo majhna, saj je lahko samo določeno zaporedje dogodkov, ki se zgodijo ob določenem času, povzročilo blokado. Murphyjev zakon, fantje, to je Murphyjev zakon.

Da bi zaščitil del kode, ki sem ga potreboval, sem zamenjal klice funkcij mutex (zgrajene na vrhu funkcionalnosti mutex OS) z majhnim izvornim paketom mutex Ada za nadzor dostopa mutexa do tega dela.

Vstavil sem ga v kodo in izvedel test. Sedem ur pozneje je koda še vedno delovala.

Moja koda je bila poslana Rationalu, kjer so jo prevedli, razstavili in preverili, da ne uporablja istega pristopa, kot je bil uporabljen v problematičnih funkcijah mutex.

To je bil najbolj natrpan pregled kode v moji karieri 🙂 Z mano je bilo v sobi približno deset inženirjev in menedžerjev, še deset ljudi je bilo na konferenčnem klicu - in vsi so pregledali približno 20 vrstic kode.

Koda je bila pregledana, nove izvedljive datoteke so bile sestavljene in poslane v formalno regresijsko testiranje. Nekaj ​​tednov kasneje je bil preizkus odštevanja uspešen in raketa je vzletela.

V redu, to je vse lepo in prav, ampak kaj je smisel zgodbe?

To je bil popolnoma gnusen problem. Na stotine tisoč vrstic kode, vzporedno izvajanje, več kot ducat medsebojno delujočih procesov, slaba arhitektura in slaba implementacija, vmesniki za vgrajene sisteme in milijoni porabljenih dolarjev. Brez pritiska, kajne.

Nisem bil edini, ki je delal na tem problemu, čeprav sem bil v središču pozornosti, ko sem izvajal prenos. Toda čeprav sem to naredil, to ne pomeni, da sem razumel vseh sto tisoč vrstic kode ali jih celo preletel. Kodo in dnevnike so analizirali inženirji po vsej državi, a ko so mi povedali svoje hipoteze o vzrokih okvare, sem potreboval le pol minute, da sem jih ovrgel. In ko so me prosili, naj analiziram teorije, sem to posredoval komu drugemu, ker mi je bilo očitno, da gredo ti inženirji v napačno smer. Zveni predrzno? Ja, to je res, vendar sem hipoteze in zahteve zavrnil iz drugega razloga.

Razumel sem naravo problema. Nisem točno vedel, kje se to dogaja in zakaj, vedel pa sem, kaj se dogaja.

Z leti sem si nabrala veliko znanja in izkušenj. Bil sem eden od pionirjev uporabe Ade in razumel sem njene prednosti in slabosti. Vem, kako izvajalne knjižnice Ada obravnavajo naloge in se ukvarjajo z vzporednim izvajanjem. In razumem nizkonivojsko programiranje na ravni pomnilnika, registrov in asemblerja. Z drugimi besedami, imam globoko znanje na svojem področju. In z njimi sem našel vzrok težave. Nisem le zaobšel hrošča, razumel sem, kako ga najti v zelo občutljivem izvajalnem okolju.

Takšne zgodbe o boju s kodo niso preveč zanimive za tiste, ki ne poznajo značilnosti in pogojev takšnega boja. Toda te zgodbe nam pomagajo razumeti, kaj je potrebno za reševanje res težkih problemov.

Če želite rešiti res težke probleme, morate biti več kot le programer. Razumeti morate »usodo« kode, kako deluje s svojim okoljem in kako samo okolje deluje.

In potem boste imeli svoj uničen počitniški teden.

Se nadaljuje.

Vir: www.habr.com

Dodaj komentar