Folklor programera i inženjera (1. dio)

Folklor programera i inženjera (1. dio)

Ovo je izbor priča sa interneta o tome kako bubice ponekad imaju potpuno nevjerovatne manifestacije. Možda i vi imate nešto za reći.

Alergija na auto na sladoled od vanile

Priča za inženjere koji razumiju da očigledno nije uvijek odgovor i da, koliko god činjenice izgledale nategnute, one su i dalje činjenice. Pontiac divizija General Motors Corporation primila je žalbu:

Ovo je drugi put da vam pišem i ne zamjeram vam što niste odgovorili, jer zvuči suludo. Naša porodica ima tradiciju da svako veče posle večere jede sladoled. Vrste sladoleda se mijenjaju svaki put, a nakon večere cijela porodica bira koji će sladoled kupiti, nakon čega idem u radnju. Nedavno sam kupio novi Pontiac i od tada su moja putovanja po sladoled postali problem. Vidite, svaki put kada kupim sladoled od vanile i vratim se iz radnje, auto ne upali. Ako donesem neki drugi sladoled, auto pali bez problema. Želim da postavim ozbiljno pitanje, ma koliko to glupo zvučalo: „Šta je to kod Pontiaca da se ne pokreće kada donesem sladoled od vanile, već se lako pokreće kada donesem drugi ukus sladoleda?“

Kao što možete zamisliti, predsjednik divizije je bio skeptičan u vezi sa pismom. Međutim, za svaki slučaj poslao sam inžinjera da provjeri. Iznenadilo ga je što ga je dočekao bogat, obrazovan čovjek koji živi u prekrasnom kraju. Dogovorili su se da se nađu odmah posle večere kako bi njih dvoje otišli u prodavnicu na sladoled. Te večeri je bila vanilija, a kada su se vratili do auta, nije htelo da upali.

Inženjer je došao još tri večeri. Prvi put sladoled je bio čokoladni. Auto je krenuo. Drugi put je bio sladoled od jagoda. Auto je krenuo. Treće večeri je tražio da uzme vanilu. Auto nije upalio.

Racionalno obrazlažući, inženjer je odbio da veruje da je automobil alergičan na sladoled od vanile. Zbog toga sam se dogovorio sa vlasnikom automobila da nastavi sa posetama dok ne nađe rešenje za problem. I usput je počeo da beleži: zapisivao je sve podatke, doba dana, vrstu benzina, vreme dolaska i povratka iz prodavnice itd.

Inženjer je ubrzo shvatio da vlasnik automobila troši manje vremena kupujući sladoled od vanile. Razlog je bio raspored robe u radnji. Sladoled od vanilije bio je najpopularniji i držan je u zasebnom zamrzivaču ispred radnje kako bi se lakše pronašao. A sve ostale sorte bile su u stražnjem dijelu radnje, i trebalo je mnogo više vremena da se pronađe prava sorta i plati.

Sada je bilo pitanje za inženjera: zašto se auto nije upalio ako je prošlo manje vremena od trenutka kada je motor ugašen? Budući da je problem bilo vrijeme, a ne sladoled od vanilije, inženjer je brzo pronašao odgovor: u pitanju je plinska brava. To se dešavalo svake večeri, ali kada je vlasnik automobila više vremena proveo tražeći sladoled, motor je uspio da se dovoljno ohladi i lako se upali. A kada je čovjek kupio sladoled od vanilije, motor je još uvijek bio previše vruć i plinska brava nije imala vremena da se otopi.

Moral: Čak su i potpuno ludi problemi ponekad stvarni.

crash Bandicoot

Bolno je ovo doživjeti. Kao programer, naviknete se da krivite svoj kod prvo, drugo, treće... i negde na desethiljadim mestu krivite kompajler. I dalje na listi već krivite opremu.

Evo moje priče o hardverskoj grešci.

Za igru ​​Crash Bandicoot napisao sam kod za učitavanje i spremanje na memorijsku karticu. Za tako samozadovoljnog programera igara to je bilo kao šetnja parkom: mislio sam da će posao trajati nekoliko dana. Međutim, završio sam s otklanjanjem grešaka u kodu šest sedmica. Usput sam rješavao i druge probleme, ali sam se svakih nekoliko dana vraćao na ovaj kod na nekoliko sati. Bila je to agonija.

Simptom je izgledao ovako: kada sačuvate trenutno igranje igre i pristupite memorijskoj kartici, gotovo uvijek sve ide u redu... Ali ponekad operacija čitanja ili pisanja istekne bez očiglednog razloga. Kratko snimanje često ošteti memorijsku karticu. Kada igrač pokuša spasiti, on ne samo da ne uspijeva spasiti, već i uništi mapu. Sranje.

Nakon nekog vremena, naša producentica u Sonyju, Connie Bus, počela je paničariti. Nismo mogli da isporučimo igru ​​sa ovom greškom, a šest nedelja kasnije nisam razumeo šta je uzrok problema. Preko Connie smo kontaktirali druge programere PS1: da li se neko susreo sa nečim sličnim? br. Niko nije imao problema sa memorijskom karticom.

Kada nemate ideje za otklanjanje grešaka, jedini pristup koji preostaje je "zavadi pa vladaj": uklonite sve više i više koda iz neispravnog programa dok ne ostane relativno mali fragment koji i dalje uzrokuje problem. Odnosno, odsecate program deo po deo dok ne ostane deo koji sadrži grešku.

Ali stvar je u tome da je vrlo teško izrezati komade iz video igre. Kako ga pokrenuti ako ste uklonili kod koji emulira gravitaciju? Ili crtanje likova?

Stoga moramo zamijeniti cijele module stubovima koji se pretvaraju da rade nešto korisno, a u stvari rade nešto vrlo jednostavno što ne može sadržavati greške. Moramo napisati takve štake da bi utakmica barem radila. Ovo je spor i bolan proces.

Ukratko, uspeo sam. Uklanjao sam sve više i više delova koda dok mi nije ostao početni kod koji konfiguriše sistem za pokretanje igre, inicijalizuje hardver za renderovanje itd. Naravno, u ovoj fazi nisam mogao da kreiram meni za spremanje i učitavanje, jer bih morao da napravim stub za sav grafički kod. Ali mogao bih da se pretvaram da sam korisnik koristeći (nevidljivi) ekran za spremanje i učitavanje i tražim da sačuvam, a zatim upišem na memorijsku karticu.

Ovo mi je ostavilo mali komad koda koji je i dalje imao gornji problem - ali se i dalje dešavao nasumično! Najčešće je sve funkcionisalo dobro, ali povremeno je bilo i kvarova. Uklonio sam skoro sav kod igre, ali greška je još uvijek živa. Ovo je bilo zbunjujuće: preostali kod zapravo nije učinio ništa.

U nekom trenutku, vjerovatno oko tri sata ujutro, pala mi je misao. Operacije čitanja i pisanja (unos/izlaz) uključuju precizna vremena izvršenja. Kada radite s tvrdim diskom, memorijskom karticom ili Bluetooth modulom, kod niskog nivoa odgovoran za čitanje i pisanje to čini u skladu s impulsima sata.

Uz pomoć sata, uređaj koji nije direktno povezan sa procesorom se sinhronizuje sa kodom koji se izvršava na procesoru. Sat određuje brzinu prenosa podataka – brzinu kojom se prenose podaci. Ako postoji zabuna s vremenskim rasporedom, onda su ili hardver ili softver, ili oboje, također zbunjeni. A to je jako loše, jer podaci mogu biti oštećeni.

Šta ako nešto u našem kodu zbuni tajminge? Provjerio sam sve u vezi s tim u kodu testnog programa i primijetio da smo programibilni tajmer u PS1 postavili na 1 kHz (1000 tikova u sekundi). Ovo je dosta; podrazumevano, kada se konzola pokrene, radi na 100 Hz. I većina igara koristi ovu frekvenciju.

Andy, programer igre, postavio je tajmer na 1 kHz kako bi se pokreti preciznije izračunavali. Andy ima tendenciju da pretjera, a ako oponašamo gravitaciju, radimo to što je preciznije moguće!

Ali što ako je ubrzanje tajmera nekako utjecalo na ukupno vrijeme programa, a samim tim i na sat koji regulira brzinu prijenosa za memorijsku karticu?

Prokomentirao sam tajmer kod. Greška se nije ponovila. Ali to ne znači da smo to popravili, jer se kvar dogodio nasumično. Šta ako sam samo imao sreće?

Nekoliko dana kasnije ponovo sam eksperimentisao sa programom testiranja. Greška se nije ponovila. Vratio sam se na punu kodnu bazu igre i izmijenio kod za spremanje i učitavanje tako da se programibilni tajmer resetirao na svoju originalnu vrijednost (100Hz) prije pristupa memorijskoj kartici, a zatim se vratio na 1kHz. Više nije bilo sudara.

Ali zašto se to dogodilo?

Ponovo sam se vratio na program testiranja. Pokušao sam pronaći neki obrazac u pojavi greške sa tajmerom od 1 kHz. Na kraju sam primijetio da se greška javlja kada se neko igra sa PS1 kontrolerom. Pošto bih to rijetko radio sam - zašto bi mi trebao kontroler prilikom testiranja koda za spremanje i učitavanje? - Nisam ni primetio ovu zavisnost. Ali jednog dana je jedan od naših umjetnika čekao da završim testiranje - vjerovatno sam u tom trenutku psovao - i nervozno vrtio kontroler u rukama. Došlo je do greške. “Čekaj, šta?!” Pa, uradi to ponovo!”

Kada sam shvatio da su ova dva događaja međusobno povezana, mogao sam lako da reprodukujem grešku: počeo sam da snimam na memorijsku karticu, pomerio kontroler i uništio memorijsku karticu. Meni je to izgledalo kao hardverska greška.

Došao sam do Connie i ispričao joj o svom otkriću. Informaciju je prenijela jednom od inženjera koji su dizajnirali PS1. “Nemoguće,” odgovorio je, “ne može biti hardverski problem.” Zamolio sam Connie da nam dogovori razgovor.

Inženjer me je nazvao i posvađali smo se na njegovom slomljenom engleskom i mom (ekstremno) slomljenom japanskom. Na kraju sam rekao: „Dozvolite mi da pošaljem svoj testni program od 30 linija gdje pomjeranje kontrolera uzrokuje grešku.“ On je pristao. Rekao je da je to gubljenje vremena i da je užasno zauzet radom na novom projektu, ali bi popustio jer smo mi bili veoma važan programer za Sony. Očistio sam svoj program za testiranje i poslao mu ga.

Sljedeće večeri (mi smo bili u Los Angelesu, a on u Tokiju) nazvao me je i stidljivo se izvinio. To je bio hardverski problem.

Ne znam u čemu je tačno greška, ali iz onoga što sam čuo u sedištu kompanije Sony, ako tajmer postavite na dovoljno visoku vrednost, on je ometao komponente na matičnoj ploči u blizini kristala tajmera. Jedan od njih je bio kontroler brzine prijenosa za memorijsku karticu, koji je također postavljao brzinu prijenosa za kontrolere. Nisam inženjer, pa sam možda nešto zabrljao.

Ali suština je da je bilo smetnji između komponenti na matičnoj ploči. A kada se istovremeno prenose podaci kroz port kontrolera i port za memorijsku karticu sa tajmerom koji radi na 1 kHz, bitovi su izgubljeni, podaci su izgubljeni i kartica je oštećena.

Loše krave

1980-ih, moj mentor Sergej je napisao softver za SM-1800, sovjetski klon PDP-11. Ovaj mikroračunar je upravo instaliran na železničkoj stanici u blizini Sverdlovska, važnog transportnog čvorišta u SSSR-u. Novi sistem je dizajniran za usmjeravanje vagona i teretnog saobraćaja. Ali sadržavao je dosadnu grešku koja je dovela do nasumičnih padova i padova. Padovi su se uvek dešavali kada bi neko otišao kući uveče. Ali uprkos detaljnoj istrazi sledećeg dana, računar je radio ispravno u svim ručnim i automatskim testovima. Ovo obično ukazuje na stanje trke ili neku drugu takmičarsku grešku koja se javlja pod određenim uslovima. Umoran od poziva kasno u noć, Sergej je odlučio da otkrije suštinu i pre svega da shvati koji su uslovi u ranžirnom kolodvoru doveli do kvara računara.

Prvo je prikupio statistiku svih neobjašnjivih padova i napravio grafikon po datumu i vremenu. Obrazac je bio očigledan. Nakon još nekoliko dana posmatranja, Sergej je shvatio da može lako predvidjeti vrijeme budućih kvarova sistema.

Ubrzo je saznao da je do poremećaja došlo samo kada je stanica sortirala vozove stoke iz sjeverne Ukrajine i zapadne Rusije koji su se uputili u obližnju klaonicu. To je samo po sebi bilo čudno, jer su klaonicu snabdevale farme koje se nalaze mnogo bliže, u Kazahstanu.

Nuklearna elektrana u Černobilu eksplodirala je 1986. godine, a radioaktivne padavine su učinile okolna područja nenastanjivim. Kontaminirana su ogromna područja u sjevernoj Ukrajini, Bjelorusiji i zapadnoj Rusiji. Sumnjajući na visok nivo radijacije u vagonima koji dolaze, Sergej je razvio metodu za testiranje ove teorije. Stanovništvu je bilo zabranjeno posedovanje dozimetara, pa se Sergej prijavio sa nekoliko vojnika na železničkoj stanici. Nakon nekoliko pića votke, uspio je uvjeriti vojnika da izmjeri nivo radijacije u jednoj od sumnjivih vagona. Pokazalo se da je nivo nekoliko puta veći od normalnih vrijednosti.

Ne samo da je stoka emitovala mnogo zračenja, njen nivo je bio toliko visok da je doveo do nasumičnih gubitaka bitova u memoriji SM-1800, koji se nalazio u zgradi pored stanice.

U SSSR-u je vladala nestašica hrane, a vlasti su odlučile da pomiješaju černobilsko meso s mesom iz drugih regija zemlje. To je omogućilo smanjenje ukupnog nivoa radioaktivnosti bez gubitka vrijednih resursa. Saznavši za to, Sergej je odmah popunio dokumente za emigraciju. I rušenje računara je prestalo samo od sebe kada se nivo radijacije smanjivao tokom vremena.

Kroz cijevi

Nekada davno, Movietech Solutions je kreirao softver za bioskope, dizajniran za računovodstvo, prodaju karata i opšte upravljanje. DOS verzija vodeće aplikacije bila je prilično popularna među malim i srednjim lancima kina u Sjevernoj Americi. Stoga nije iznenađujuće da je, kada je najavljena verzija Windows 95, integrirana s najnovijim ekranima osjetljivim na dodir i samouslužnim kioscima, i opremljena svim vrstama alata za prijavu, brzo postala i popularna. Najčešće je ažuriranje prošlo bez problema. Lokalno IT osoblje instaliralo je novu opremu, migrirali podatke i posao je nastavljen. Osim kada nije trajalo. Kada bi se to dogodilo, kompanija bi poslala Jamesa, zvanog "Čistač".

Iako nadimak sugerira podli tip, čistač je samo kombinacija instruktora, instalatera i majstora. Džejms bi proveo nekoliko dana na lokaciji klijenta sastavljajući sve komponente zajedno, a zatim bi proveo još nekoliko dana podučavajući osoblje kako da koriste novi sistem, rešavajući sve hardverske probleme koji su se pojavili i suštinski pomažući softveru u povoju.

Stoga ne čudi što je u ovim užurbanim vremenima James ujutro stigao u kancelariju, a prije nego što je stigao do svog stola, dočekao ga je menadžer, prepun kofeina preko uobičajenog.

"Bojim se da morate što prije otići u Annapolis, Nova Škotska." Cijeli im se sistem pokvario, a nakon noći rada sa njihovim inženjerima, ne možemo shvatiti šta se dogodilo. Izgleda da je mreža na serveru otkazala. Ali tek nakon što je sistem radio nekoliko minuta.

— Nisu se vratili na stari sistem? - odgovorio je Džejms potpuno ozbiljno, iako je mentalno razrogačio oči od iznenađenja.

— Upravo tako: njihov IT stručnjak je „promijenio prioritete“ i odlučio da ode sa svojim starim serverom. James, instalirali su sistem na šest lokacija i upravo platili premium podršku, a njihov posao se sada vodi kao 1950-ih.

James se lagano uspravio.

- To je druga stvar. Ok, počnimo.

Kada je stigao u Annapolis, prvo što je uradio bilo je da je pronašao prvo pozorište mušterije koje je imalo problem. Na karti snimljenoj na aerodromu sve je izgledalo pristojno, ali je područje oko željene adrese izgledalo sumnjivo. Nije geto, već podsjeća na film noir. Dok je James parkirao na ivičnjaku u centru grada, prišla mu je prostitutka. S obzirom na veličinu Annapolisa, najvjerovatnije je bio jedini u cijelom gradu. Njena pojava odmah je podsetila poznatog lika koji je na velikom platnu nudio seks za novac. Ne, ne o Juliji Roberts, već o Jonu Voightu [aluzija na film "Ponoćni kauboj" - cca. lane].

Poslavši prostitutku na put, Džejms je otišao u bioskop. Okolina je postala bolja, ali je i dalje ostavljala utisak da je dotrajala. Nije da je James bio previše zabrinut. Bio je na bednim mestima ranije. A ovo je bila Kanada, gdje su čak i pljačkaši dovoljno ljubazni da kažu "hvala" nakon što vam uzmu novčanik.

Bočni ulaz u bioskop bio je u vlažnoj uličici. James je prišao vratima i pokucao. Ubrzo je zaškripao i lagano se otvorio.

-Jeste li čistačica? - promukao je glas iznutra.

- Da, ja sam... Došao sam da sve popravim.

James je ušao u predvorje bioskopa. Očigledno nije bilo drugog izbora, osoblje je počelo da deli papirne karte posetiocima. To je otežavalo finansijsko izvještavanje, a kamoli zanimljivije detalje. Ali osoblje je dočekalo Džejmsa sa olakšanjem i odmah ga odvelo u sobu za servere.

Na prvi pogled sve je bilo u redu. James se prijavio na server i provjerio uobičajena sumnjiva mjesta. Nema problema. Međutim, iz obilja opreza, James je isključio server, zamijenio mrežnu karticu i vratio sistem. Odmah je počela sa radom u potpunosti. Osoblje je ponovo počelo prodavati karte.

James je nazvao Marka i obavijestio ga o situaciji. Nije teško zamisliti da bi James želio ostati i vidjeti hoće li se dogoditi nešto neočekivano. Sišao je niz stepenice i počeo da pita zaposlene šta se dogodilo. Očigledno je sistem prestao da radi. Isključili su ga i uključili, sve je radilo. Ali nakon 10 minuta sistem je pao.

Upravo u ovom trenutku dogodilo se nešto slično. Odjednom je sistem za prodaju karata počeo da ispušta greške. Osoblje je uzdahnulo i zgrabilo papirnate karte, a Džejms je požurio u sobu za servere. Sve je izgledalo dobro sa serverom.

Zatim je ušao jedan od zaposlenih.

— Sistem ponovo radi.

Džejms je bio zbunjen jer ništa nije uradio. Tačnije, ništa što bi natjeralo sistem da radi. Odjavio se, uzeo telefon i nazvao liniju za podršku svoje kompanije. Ubrzo je isti zaposlenik ušao u server sobu.

- Sistem je pao.

Džejms je bacio pogled na server. Zanimljiv i poznat uzorak raznobojnih oblika plesao je na ekranu - haotično se uvijaju i isprepliću cijevi. Svi smo u nekom trenutku vidjeli ovaj screensaver. Bilo je predivno prikazano i doslovno hipnotizirajuće.


Džejms je pritisnuo dugme i šablon je nestao. Požurio je do blagajne i na putu sreo službenicu koja mu se vraćala.

— Sistem ponovo radi.

Ako možete da uradite mentalni facepalm, to je upravo ono što je Džejms uradio. Screensaver. Koristi OpenGL. I stoga, tokom rada, troši sve resurse serverskog procesora. Kao rezultat, svaki poziv serveru završava s timeoutom.

Džejms se vratio u serversku sobu, prijavio se i zamenio čuvar ekrana prelepim cevima sa praznim ekranom. Odnosno, umjesto screensaver-a koji troši 100% procesorskih resursa, instalirao sam drugi koji ne troši resurse. Onda sam čekao 10 minuta da provjerim svoju pretpostavku.

Kada je Džejms stigao u sledeći bioskop, pitao se kako da objasni svom menadžeru da je upravo preleteo 800 km da isključi čuvar ekrana.

Pad u određenoj fazi mjeseca

Istinita priča. Jednog dana pojavila se softverska greška koja je zavisila od faze meseca. Postojala je mala rutina koja se obično koristila u raznim MIT programima za izračunavanje aproksimacije pravoj fazi Mjeseca. GLS je ovu rutinu ugradio u LISP program koji bi, prilikom pisanja datoteke, izbacio red sa vremenskom oznakom dugom skoro 80 znakova. Vrlo rijetko je prvi red poruke na kraju bio predugačak i vodio do sljedećeg reda. A kada je program kasnije pročitao ovaj fajl, opsovao je. Dužina prvog reda zavisila je od tačnog datuma i vremena, kao i od dužine specifikacije faze u vreme štampanja vremenske oznake. Odnosno, buba je bukvalno zavisila od faze meseca!

Prvo papirno izdanje Žargon File (Steele-1983) sadržavao je primjer takve linije koja je dovela do opisane greške, ali ju je slagač "popravio". Ovo je od tada opisano kao "buga u fazi mjeseca".

Ipak, budite oprezni s pretpostavkama. Prije nekoliko godina, inženjeri iz CERN-a (Evropski centar za nuklearna istraživanja) naišli su na greške u eksperimentima provedenim na Velikom sudaraču elektrona i pozitrona. Budući da kompjuteri aktivno obrađuju ogromnu količinu podataka koje generiše ovaj uređaj prije nego što pokažu rezultat naučnicima, mnogi su nagađali da je softver na neki način osjetljiv na fazu mjeseca. Nekoliko očajnih inženjera je došlo do dna istine. Greška je nastala zbog male promjene geometrije prstena dugog 27 km zbog deformacije Zemlje tokom prolaska Mjeseca! Ova priča je ušla u folklor fizike kao "Newtonova osveta fizici čestica" i primjer veze između najjednostavnijih i najstarijih zakona fizike i najnaprednijih naučnih koncepata.

Ispiranje toaleta zaustavlja voz

Najbolja hardverska greška za koju sam ikada čuo bila je u brzom vozu u Francuskoj. Buba je dovela do naglog kočenja voza, ali samo ako je u njemu bilo putnika. U svakom takvom slučaju, voz je povučen iz saobraćaja, provjeren, ali ništa nije pronađeno. Zatim je vraćen na liniju i on se odmah zaustavio.

Tokom jedne od provera, inženjer koji je putovao u vozu otišao je u toalet. Ubrzo je oprao, BUM! Hitno zaustavljanje.

Inženjer je kontaktirao vozača i pitao:

— Šta ste radili neposredno pre kočenja?

- Pa, usporio sam na spustu...

Ovo je bilo čudno, jer tokom normalnog rada voz usporava na spuštanjima na desetine puta. Voz je krenuo dalje, a na sledećem spuštanju mašinovođa je upozorio:

- Usporiću.

Ništa se nije dogodilo.

— Šta ste radili tokom zadnjeg kočenja? - upitao je vozač.

- Pa... bio sam u toaletu...

- Pa, onda idi u toalet i uradi ono što si uradio kad opet siđemo!

Inženjer je otišao u toalet, a kada je vozač upozorio: „Usporavam“, ispustio je vodu. Naravno, voz je odmah stao.

Sada su mogli reproducirati problem i morali su pronaći uzrok.

Nakon dva minuta uočili su da je kabl za daljinsko upravljanje motornom kočnicom (voz je imao po jedan motor na svakom kraju) bio odspojen sa zida elektro ormana i da leži na releju koji je upravljao solenoidom utikača WC šolje... Kada je relej bio uključen, stvarao je smetnje u kočionom sajlu, a zaštita sistema od kvarova jednostavno je uključivala kočenje u nuždi.

Kapija koja je mrzela FORTRAN

Prije nekoliko mjeseci primijetili smo da mrežne veze na kopnu [ovo je bilo na Havajima] postaju veoma, vrlo spore. To može trajati 10-15 minuta, a onda se iznenada ponoviti. Nakon nekog vremena, kolega mi se požalio da su mrežne veze na kopnu uopšte ne radi. Imao je neki FORTRAN kod koji je trebalo kopirati na mašinu na kopnu, ali nije mogao jer "mreža nije izdržala dovoljno dugo da se FTP upload završi."

Da, ispostavilo se da je došlo do kvarova na mreži kada je kolega pokušao FTP datoteku sa izvornim kodom na FORTRAN-u na mašinu na kopnu. Pokušali smo da arhiviramo fajl: onda je kopiran glatko (ali ciljna mašina nije imala raspakivač, tako da problem nije rešen). Konačno smo "podijelili" FORTRAN kod na vrlo male dijelove i poslali ih jedan po jedan. Većina fragmenata je kopirana bez problema, ali nekoliko komada nije prošlo, ili je prošlo nakon brojni pokušaji.

Nakon ispitivanja problematičnih pasusa, otkrili smo da imaju nešto zajedničko: svi su sadržavali blokove komentara koji su započinjali i završavali redovima koji se sastoje od velikog C (kao što je kolega više volio komentarisati u FORTRANU). Poslali smo e-poštu mrežnim stručnjacima na kopnu i zatražili pomoć. Naravno, hteli su da vide uzorke naših fajlova koji se ne mogu preneti preko FTP-a... ali naša pisma nisu stigla do njih. Konačno smo došli do jednostavnog opisatikako izgledaju neprenosivi fajlovi. Upalilo je :) [Usuđujem li se ovdje dodati primjer jednog od problematičnih FORTRAN komentara? Verovatno nije vredno toga!]

Na kraju smo to uspjeli shvatiti. Nedavno je postavljen novi gateway između našeg dijela kampusa i kopnene mreže. Imao je OGROMNE poteškoće u prijenosu paketa koji su sadržavali ponovljene bitove velikih slova C! Samo nekoliko od ovih paketa moglo bi zauzeti sve resurse gatewaya i spriječiti većinu drugih paketa da prođu. Požalili smo se proizvođaču gateway-a... a oni su odgovorili: „O, da, suočeni ste sa greškom ponovljenog C! Već znamo za njega.” Na kraju smo riješili problem kupovinom novog gatewaya od drugog proizvođača (u odbranu prvog, nemogućnost prijenosa FORTRAN programa za neke može biti prednost!).

Teška vremena

Prije nekoliko godina, dok sam radio na kreiranju ETL sistema u Perlu kako bih smanjio troškove kliničkih ispitivanja faze 40, morao sam obraditi oko 000 datuma. Njih dvoje nisu položili test. To me nije previše zasmetalo jer su ovi datumi uzeti iz podataka koje je dao klijent koji je često bio, da tako kažemo, iznenađujući. Ali kada sam proverio originalne podatke, ispostavilo se da su to bili 1. januar 2011. i 1. januar 2007. Mislio sam da je greška sadržana u programu koji sam upravo napisao, ali se ispostavilo da je već prošlo 30 godina. star. Ovo može zvučati misteriozno onima koji nisu upoznati sa softverskim ekosistemom. Zbog dugogodišnje odluke druge kompanije da zaradi novac, moj klijent mi je platio da popravim grešku koju je jedna kompanija uvela slučajno, a druga namerno. Da biste razumeli o čemu govorim, moram da govorim o kompaniji koja je dodala funkciju koja je na kraju postala greška, kao i o nekoliko drugih zanimljivih događaja koji su doprineli misterioznoj grešci koju sam ispravio.

U stara dobra vremena, Apple računari su ponekad spontano resetovali datum na 1. januar 1904. Razlog je bio jednostavan: koristio je “sistemski sat” na baterije za praćenje datuma i vremena. Šta se desilo kada se baterija ispraznila? Računari su počeli da prate datum po broju sekundi od početka epohe. Pod epohom smo mislili na referentni originalni datum, a za Macintosh je to bio 1. januar 1904. A nakon što se baterija ispraznila, trenutni datum je resetovan na navedeni. Ali zašto se to dogodilo?

Ranije je Apple koristio 32 bita za pohranjivanje broja sekundi od originalnog datuma. Jedan bit može pohraniti jednu od dvije vrijednosti - 1 ili 0. Dva bita mogu pohraniti jednu od četiri vrijednosti: 00, 01, 10, 11. Tri bita - jedna vrijednost od osam: 000, 001, 010, 011, 100 , 101, 110, 111, itd. A 32 može pohraniti jednu od 232 vrijednosti, odnosno 4 sekundi. Za Apple datume, ovo je bilo oko 294 godina, tako da stariji Macovi ne mogu podnijeti datume nakon 967. A ako se baterija sistema isprazni, datum se resetuje na 296 sekundi od početka epohe i morate ručno da podesite datum svaki put kada uključite računar (ili dok ne kupite novu bateriju).

Međutim, Appleova odluka da datume pohranjuje kao sekunde od epohe značila je da ne možemo obraditi datume prije epohe, što je imalo dalekosežne posljedice, kao što ćemo vidjeti. Apple je predstavio funkciju, a ne grešku. Između ostalog, to je značilo da je Macintosh operativni sistem imun na „milenijumsku grešku“ (što se ne može reći za mnoge Mac aplikacije koje su imale sopstvene sisteme datuma da bi zaobišli ograničenja).

Nastavi. Koristili smo Lotus 1-2-3, IBM-ovu "ubitačnu aplikaciju" koja je pomogla u pokretanju PC revolucije, iako su Appleovi računari imali VisiCalc, što je osobno računalo učinilo uspješnim. Iskreno rečeno, da se 1-2-3 nije pojavio, računari teško da bi uzeli maha, a istorija personalnih računara mogla bi se razvijati sasvim drugačije. Lotus 1-2-3 pogrešno je tretirao 1900. kao prijestupnu godinu. Kada je Microsoft objavio svoju prvu tabelu, Multiplan, zauzeo je mali dio tržišta. A kada su pokrenuli Excel projekat, odlučili su ne samo da kopiraju šemu imenovanja redova i stupaca iz Lotusa 1-2-3, već i da osiguraju kompatibilnost s greškama tako što su 1900. namjerno tretirali kao prijestupnu godinu. Ovaj problem postoji i danas. To jest, u 1-2-3 ovo je bila greška, ali u Excelu je to bila svjesna odluka koja je osigurala da svi 1-2-3 korisnici mogu uvesti svoje tabele u Excel bez promjene podataka, čak i ako su netačni.

Ali postojao je još jedan problem. Prvo, Microsoft je objavio Excel za Macintosh, koji nije prepoznao datume prije 1. januara 1904. A u Excelu se 1. januar 1900. smatrao početkom ere. Stoga su programeri napravili promjenu tako da je njihov program prepoznao tip ere i pohranio podatke u sebe u skladu sa željenom erom. Microsoft je čak napisao članak s objašnjenjem o tome. I ova odluka je dovela do moje greške.

Moj ETL sistem je primio Excel tabele od kupaca koje su kreirane na Windows-u, ali se mogu kreirati i na Mac-u. Stoga bi početak ere u tabeli mogao biti ili 1. januar 1900. ili 1. januar 1904. godine. Kako to saznati? Format Excel datoteke prikazuje potrebne informacije, ali parser koji sam koristio nije ih pokazao (sada jeste), i pretpostavlja da znate epohu za određenu tabelu. Vjerovatno sam mogao potrošiti više vremena na razumijevanje binarnog formata Excela i slanje zakrpe autoru parsera, ali sam imao još mnogo toga da uradim za klijenta, pa sam brzo napisao heuristiku da odredim epohu. Bila je jednostavna.

U Excelu se datum 5. jul 1998. može predstaviti u formatu "07-05-98" (beskorisni američki sistem), "5. jul 98", "5. jul 1998", "5-jul-98" ili neki drugi format, drugi beskorisni format (ironično, jedan od formata koji moja verzija Excela nije nudila bio je ISO 8601). Međutim, unutar tabele, neformatirani datum je pohranjen kao "35981" za epohu-1900 ili "34519" za epohu-1904 (brojevi predstavljaju broj dana od epohe). Jednostavno sam koristio jednostavan parser da izdvojim godinu iz formatiranog datuma, a zatim koristim Excel parser da izdvojim godinu iz neformatiranog datuma. Ako su se obje vrijednosti razlikovale za 4 godine, onda sam znao da koristim sistem sa epohom-1904.

Zašto jednostavno nisam koristio formatirane datume? Zato što se 5. jul 1998. može formatirati kao "juli 98" sa izgubljenim danom u mjesecu. Dobili smo tabele od toliko kompanija koje su ih kreirale na toliko različitih načina da je na nama (u ovom slučaju, meni) bilo da odredimo datume. Osim toga, ako Excel to dobro shvati, trebali bismo i mi!

U isto vrijeme naišao sam na 39082. Dozvolite mi da vas podsjetim da je Lotus 1-2-3 1900. smatrao prijestupnom godinom, i to je vjerno ponovljeno u Excelu. A pošto je ovo dodao jedan dan 1900. godini, mnoge funkcije izračunavanja datuma mogle bi biti pogrešne baš za taj dan. To jest, 39082 je mogao biti 1. januar 2011. (na Mac računarima) ili 31. decembar 2006. (na Windows-u). Ako je moj "parser godine" izdvojio 2011. godinu iz formatirane vrijednosti, onda je sve u redu. Ali pošto Excel parser ne zna koja epoha se koristi, podrazumevano je epoha-1900, vraćajući 2006. godinu. Moja aplikacija je vidjela da je razlika 5 godina, smatrala je to greškom, zabilježila je i vratila neformatiranu vrijednost.

Da zaobiđem ovo, napisao sam ovo (pseudokod):

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

A onda je svih 40 datuma raščlanjeno ispravno.

Usred velikih poslova štampanja

Početkom 1980-ih, moj otac je radio u Storage Technology, sada nepostojećem odjelu koji je kreirao pogone traka i pneumatske sisteme za brzo punjenje trake.

Redizajnirali su pogone tako da mogu imati jedan centralni “A” disk povezan sa sedam “B” diskova, a mali OS u RAM-u koji je kontrolirao “A” pogon mogao je delegirati operacije čitanja i pisanja na sve “B” diskove.

Svaki put kada je pogon “A” pokrenut, bilo je potrebno ubaciti flopi disk u periferni drajv povezan na “A” kako bi se operativni sistem učitao u njegovu memoriju. Bilo je izuzetno primitivno: računarsku snagu je obezbeđivao 8-bitni mikrokontroler.

Ciljna publika za ovakvu opremu bile su kompanije sa veoma velikim skladištima podataka - banke, maloprodajni lanci, itd. - kojima je bilo potrebno štampati mnogo adresnih nalepnica ili bankovnih izvoda.

Jedan klijent je imao problem. Usred zadatka za štampanje, jedan određeni disk "A" mogao bi prestati da radi, što bi dovelo do zastoja celog posla. Da bi vratili rad diska, osoblje je moralo sve ponovo pokrenuti. A ako se to dogodilo usred šestosatnog zadatka, tada je izgubljena ogromna količina skupog kompjuterskog vremena i poremećen je raspored cijele operacije.

Tehničari su poslati iz Storage Technologies. Ali uprkos svim naporima, nisu uspeli da reprodukuju grešku pod uslovima testiranja: činilo se da se dešava usred velikih zadataka štampanja. Problem nije bio hardver, zamenili su sve što su mogli: RAM, mikrokontroler, flopi drajv, svaki zamislivi deo trake - problem je i dalje prisutan.

Tada su tehničari pozvali štab i pozvali Eksperta.

Ekspert je zgrabio stolicu i šoljicu kafe, seo u kompjutersku sobu – u to vreme postojale su sobe posvećene kompjuterima – i posmatrao kako osoblje čeka veliki posao za štampanje. Vještak je čekao da dođe do neuspjeha - i to se dogodilo. Svi su pogledali Eksperta, ali on nije imao pojma zašto se to dogodilo. Zato je naredio da se posao ponovo stavi u red, a svo osoblje i tehničari su se vratili na posao.

Stručnjak je ponovo sjeo u stolicu i počeo čekati neuspjeh. Prošlo je oko šest sati i došlo je do kvara. Ekspert opet nije imao ideje, osim da se sve dešavalo u prostoriji punoj ljudi. Naredio je da se misija ponovo pokrene, vratio se i čekao.

Do trećeg neuspjeha, Stručnjak je nešto primijetio. Greška se dogodila kada je osoblje promijenilo trake na stranom disku. Štaviše, kvar je nastao čim je jedan od zaposlenih prošao kroz određenu pločicu na podu.

Uzdignuti pod je napravljen od aluminijskih pločica postavljenih na visini od 6 do 8 inča. Brojne žice iz kompjutera su prolazile ispod podignutog poda kako bi spriječile da bilo ko slučajno nagazi važan kabel. Pločice su bile položene vrlo čvrsto kako bi se spriječilo da krhotine uđu ispod podignutog poda.

Vještak je shvatio da je jedna od pločica deformisana. Kada je zaposlenik stao na njegov ugao, rubovi pločice su trljali o susjedne pločice. Plastični dijelovi koji su spajali pločice također su trljali s njima, što je izazvalo statička mikropražnjenja koja su stvarala radiofrekventne smetnje.

Danas je RAM mnogo bolje zaštićen od radio frekvencijskih smetnji. Ali tih godina to nije bio slučaj. Stručnjak je shvatio da je ova smetnja poremetila memoriju, a sa njom i rad operativnog sistema. Pozvao je službu za podršku, naručio nove pločice, sam ih postavio i problem je nestao.

Plima je!

Priča se odigrala u server sobi, na četvrtom ili petom spratu kancelarije u Portsmouthu (mislim), u zoni dokova.

Jednog dana se srušio Unix server sa glavnom bazom podataka. Ponovo su ga pokrenuli, ali je on zadovoljno nastavio da pada iznova i iznova. Odlučili smo da pozovemo nekoga iz službe za podršku.

Momak iz podrške... Mislim da se zvao Mark, ali to nije važno... Mislim da ga ne poznajem. Nije bitno, zaista. Hajde da se držimo Marka, ok? Odlično.

Dakle, nekoliko sati kasnije došao je Mark (nije daleko od Leedsa do Portsmoutha, znate), uključio server i sve je radilo bez problema. Tipična prokleta podrška, klijent se jako uznemiri zbog ovoga. Mark pregledava datoteke evidencije i ne nalazi ništa loše. Dakle, Mark se vraća u voz (ili kojim god načinom prevoza je stigao, mogla je to biti hroma krava koliko znam... u svakom slučaju, nema veze, u redu?) i kreće nazad u Leeds, protraćivši dan.

Iste večeri server se ponovo ruši. Priča je ista... server se ne diže. Mark pokušava daljinski pomoći, ali klijent ne može pokrenuti server.

Još jedan voz, autobus, beze od limuna ili neko drugo sranje, i Mark se vratio u Portsmouth. Vidite, server se pokreće bez problema! Čudo. Mark provodi nekoliko sati provjeravajući da li je sve u redu sa operativnim sistemom ili softverom i kreće za Leeds.

Oko sredine dana server se ruši (samo polako!). Ovaj put se čini razumnim dovesti ljude za hardversku podršku da zamijene server. Ali ne, nakon otprilike 10 sati i ona pada.

Situacija se ponavljala nekoliko dana. Server radi, ruši se nakon otprilike 10 sati i ne pokreće se naredna 2 sata. Provjerili su hlađenje, curenje memorije, provjerili sve, ali ništa nisu našli. Onda su padovi prestali.

Sedmica je prošla bezbrižno... svi su bili srećni. Sretan dok sve ne počne iznova. Slika je ista. 10 sati rada, 2-3 sata zastoja...

A onda je neko (mislim da su mi rekli da ta osoba nema nikakve veze sa IT) rekao:

"To je plima!"

Uzvik je dočekan praznim pogledima, a nečija ruka je vjerovatno oklevala na dugmetu za poziv sigurnosti.

"Prestaje raditi s plimom."

Čini se da je ovo potpuno stran koncept radnicima IT podrške, koji vjerovatno neće čitati Tide Yearbook dok sjede na kafi. Objasnili su da to nikako ne može biti povezano sa plimom, jer je server radio nedelju dana bez kvarova.

“Prošle sedmice je plima bila niska, ali ove sedmice je visoka.”

Malo terminologije za one koji nemaju dozvolu za jahtu. Plima i oseka zavise od lunarnog ciklusa. I dok se Zemlja rotira, svakih 12,5 sati gravitaciono privlačenje Sunca i Mjeseca stvara plimni talas. Na početku ciklusa od 12,5 sati je plima, sredinom ciklusa je oseka, a na kraju opet plima. Ali kako se mjesečeva orbita mijenja, tako se mijenja i razlika između oseke i oseke. Kada se Mjesec nalazi između Sunca i Zemlje ili na suprotnoj strani Zemlje (pun mjesec ili bez mjeseca), dobijamo Syzygyn plime - najveće plime i najniže oseke. U pola mjeseca dobivamo kvadraturne plime - najniže plime. Razlika između ova dva ekstrema se značajno smanjuje. Lunarni ciklus traje 28 dana: sizigijan - kvadratura - sizigijan - kvadratura.

Kada je tehničarima objašnjena suština plimnih sila, odmah su pomislili da treba da pozovu policiju. I sasvim logično. Ali ispostavilo se da je tip bio u pravu. Dvije sedmice ranije, nedaleko od ureda privezan je razarač. Svaki put kada bi ga plima podigla na određenu visinu, brodski radarski stub bi završio na nivou poda serverske sobe. A radar (ili oprema za elektronsko ratovanje, ili neka druga vojna igračka) je stvorio haos u kompjuterima.

Letna misija za raketu

Dobio sam zadatak da prenesem veliki (oko 400 hiljada linija) sistem za kontrolu i praćenje lansiranja raketa na nove verzije operativnog sistema, kompajlera i jezika. Tačnije, od Solarisa 2.5.1 do Solarisa 7, i od Verdix Ada Development Systema (VADS), napisanog u Adi 83, do Rational Apex Ada sistema, napisanog u Adi 95. VADS je kupio Rational, a njegov proizvod je zastarjelo, iako je Rational pokušao implementirati kompatibilne verzije paketa specifičnih za VADS kako bi olakšao prijelaz na Apex kompajler.

Tri osobe su mi pomogle da čisto kompajliram kod. Trebalo je dvije sedmice. A onda sam sam radio na tome da sistem radi. Ukratko, to je bila najgora arhitektura i implementacija softverskog sistema na koju sam se susreo, tako da je trebalo još dva mjeseca da se završi port. Sistem je potom predat na testiranje, koje je trajalo još nekoliko mjeseci. Odmah sam ispravio greške koje su pronađene tokom testiranja, ali se njihov broj brzo smanjio (izvorni kod je bio proizvodni sistem, tako da je njegova funkcionalnost radila prilično pouzdano, samo sam morao ukloniti greške koje su se pojavile prilikom adaptacije na novi kompajler). Na kraju, kada je sve funkcionisalo kako treba, prebačen sam na drugi projekat.

A u petak prije Dana zahvalnosti zazvonio je telefon.

Lansiranje rakete trebalo je da bude testirano za oko tri nedelje, a tokom laboratorijskih ispitivanja odbrojavanja je blokiran redosled komandi. U stvarnom životu ovo bi prekinulo testiranje, a ako bi do blokade došlo u roku od nekoliko sekundi od pokretanja motora, u pomoćnim sistemima bi se dogodilo nekoliko nepovratnih radnji koje bi zahtijevale dugu - i skupu - pripravnost rakete. Ne bi počelo, ali mnogi ljudi bi bili jako uznemireni zbog gubitka vremena i mnogo, puno novca. Nemojte dozvoliti da vam iko kaže da Ministarstvo odbrane troši novac nepromišljeno – nikada nisam sreo menadžera koji je izvršio ugovore koji nije stavio budžet na prvo ili drugo mjesto, a zatim na raspored.

Prethodnih mjeseci, ovaj izazov odbrojavanja je pokrenut stotine puta u mnogim varijantama, sa samo nekoliko manjih štucanja. Tako da je vjerovatnoća da se to dogodi bila vrlo mala, ali su posljedice bile vrlo značajne. Pomnožite oba ova faktora i shvatit ćete da su vijesti predviđale uništenu prazničnu sedmicu za mene i desetine inženjera i menadžera.

I pažnja je posvećena meni kao osobi koja je portirala sistem.

Kao i kod većine bezbednosno kritičnih sistema, mnogo parametara je evidentirano, tako da je bilo prilično lako identifikovati nekoliko linija koda koje su izvršene pre nego što se sistem srušio. I naravno, nije bilo apsolutno ničeg neobičnog u vezi s njima; isti izrazi su uspješno izvedeni bukvalno hiljadama puta tokom iste vožnje.

Pozvali smo ljude iz Apexa u Rational jer su oni ti koji su razvili kompajler i neke od rutina koje su razvili bile su pozvane u sumnjivom kodu. Oni (i svi ostali) bili su impresionirani da postoji potreba da se dođe do korijena problema od doslovno nacionalnog značaja.

Budući da u časopisima nije bilo ništa zanimljivo, odlučili smo da pokušamo reproducirati problem u lokalnoj laboratoriji. Ovo nije bio lak zadatak budući da se događaj dešavao otprilike jednom na 1000 vožnji. Jedan od razloga za sumnju bio je poziv na mutex funkciju koju je razvio dobavljač (dio VADS paketa za migraciju) Unlock nije dovelo do otključavanja. Nit za obradu koja je pozvala funkciju obrađivala je poruke otkucaja srca, koje su nominalno stizale svake sekunde. Podigli smo frekvenciju na 10 Hz, odnosno 10 puta u sekundi, i počeli trčati. Otprilike sat vremena kasnije sistem se sam zaključao. U logu smo vidjeli da je redoslijed snimljenih poruka isti kao i tokom neuspjelog testa. Napravili smo još nekoliko vožnji, sistem je konstantno blokiran 45-90 minuta nakon starta, i svaki put je dnevnik sadržavao istu rutu. Iako smo tehnički koristili drugačiji kod - učestalost poruka je bila drugačija - ponašanje sistema je bilo isto, tako da smo bili uvjereni da ovaj scenario učitavanja uzrokuje isti problem.

Sada je trebalo da shvatimo gde se tačno dogodilo blokiranje u nizu izraza.

Ova implementacija sistema koristila je sistem zadataka Ada, i koristila ga je neverovatno loše. Zadaci su istovremeno izvršna konstrukcija visokog nivoa u Adi, nešto poput niti izvršavanja, samo ugrađena u sam jezik. Kada dva zadatka treba da komuniciraju, oni "odgovaraju sastanak", razmjenjuju potrebne podatke, a zatim zaustavljaju sastanak i vraćaju se na svoja nezavisna izvršenja. Međutim, sistem je drugačije implementiran. Nakon što je ciljni zadatak bio randevu, taj ciljni zadatak se sastajao s drugim zadatkom, koji se zatim sastajao s trećim zadatkom, i tako dalje dok se neka obrada ne završi. Nakon toga, svi ovi sastanci su završeni i svaki zadatak se morao vratiti svom izvršenju. Odnosno, radili smo sa najskupljim sistemom pozivanja funkcija na svetu, koji je zaustavio ceo proces „multitaskinga“ dok je obrađivao deo ulaznih podataka. A ranije to nije dovodilo do problema samo zato što je propusnost bila vrlo mala.

Opisao sam ovaj mehanizam zadatka jer kada je sastanak bio zatražen ili se očekivalo da će se završiti, moglo bi se dogoditi "promjena zadataka". To jest, procesor bi mogao početi obraditi drugi zadatak koji je spreman za izvršenje. Ispostavilo se da kada je jedan zadatak spreman za sastanak s drugim zadatkom, potpuno drugačiji zadatak može početi da se izvršava, i na kraju se kontrola vraća na prvi sastanak. Mogu se pojaviti i drugi događaji koji uzrokuju promjenu zadatka; jedan takav događaj je poziv sistemskoj funkciji, kao što je štampanje ili izvršavanje muteksa.

Da bih shvatio koja linija koda uzrokuje problem, morao sam pronaći način da zabilježim napredak kroz niz naredbi bez aktiviranja prebacivanja zadataka, što bi spriječilo da dođe do pada. Tako da nisam mogao da iskoristim prednost Put_Line()kako biste izbjegli izvođenje I/O operacija. Mogao bih postaviti varijablu brojača ili nešto slično, ali kako da vidim njenu vrijednost ako je ne mogu prikazati na ekranu?

Takođe, prilikom ispitivanja dnevnika, pokazalo se da, uprkos zamrzavanju u obradi srčanih poruka, koje je blokiralo sve I/O operacije procesa i onemogućavalo obavljanje druge obrade, ostali nezavisni zadaci nastavljaju da se izvršavaju. Odnosno, rad nije u potpunosti blokiran, već samo (kritični) lanac zadataka.

Ovo je bio trag potreban za procjenu izraza za blokiranje.

Napravio sam Ada paket koji je sadržavao zadatak, nabrojani tip i globalnu varijablu tog tipa. Brojni literali bili su vezani za specifične izraze problematične sekvence (npr. Incrementing_Buffer_Index, Locking_Mutex, Mutex_Unlocked), a zatim u njega umetnuo izraze za dodjelu koji su dodijelili odgovarajuće nabrajanje globalnoj varijabli. Budući da je objektni kod svega ovoga jednostavno pohranio konstantu u memoriju, prebacivanje zadataka kao rezultat njegovog izvršenja bilo je krajnje malo vjerovatno. Prvenstveno smo bili sumnjičavi prema izrazima koji bi mogli promijeniti zadatak, budući da se blokiranje dogodilo pri izvršavanju, a ne vraćanju pri prebacivanju zadatka nazad (iz nekoliko razloga).

Zadatak praćenja se jednostavno izvodio u petlji i povremeno provjerava da li se vrijednost globalne varijable promijenila. Sa svakom promjenom, vrijednost je pohranjena u datoteku. Zatim kratko čekanje i nova provjera. Napisao sam varijablu u datoteku jer se zadatak izvršavao samo kada ga je sistem odabrao za izvršenje prilikom prebacivanja zadatka u problemskom području. Što god se dogodilo u ovom zadatku, neće utjecati na druge, nepovezane blokirane zadatke.

Očekivalo se da kada sistem dođe do tačke izvršavanja problematičnog koda, globalna varijabla će biti resetovana prilikom prelaska na svaki sljedeći izraz. Tada će se dogoditi nešto što uzrokuje promjenu zadatka, a pošto je njegova frekvencija izvršavanja (10 Hz) niža od one zadatka nadgledanja, monitor bi mogao uhvatiti vrijednost globalne varijable i zapisati je. U normalnoj situaciji, mogao bih dobiti ponavljajući niz podskupa nabrajanja: posljednje vrijednosti varijable u trenutku prebacivanja zadatka. Kada visi, globalna varijabla se više ne bi trebala mijenjati, a posljednja upisana vrijednost će pokazati koji izraz nije završen.

Proveo sam kod sa praćenjem. Ukočio se. A nadzor je radio kao sat.

Dnevnik je sadržavao očekivani niz, koji je prekinut vrijednošću koja ukazuje da je mutex pozvan Unlock, a zadatak nije završen - kao što je slučaj sa hiljadama prethodnih poziva.

Apex inženjeri su grozničavo analizirali svoj kod u ovom trenutku i pronašli mjesto u mutexu gdje bi, teoretski, moglo doći do zaključavanja. Ali njegova vjerovatnoća je bila vrlo mala, budući da je samo određeni niz događaja koji se dogodio u određeno vrijeme mogao dovesti do blokiranja. Murphyjev zakon, momci, to je Murphyjev zakon.

Da zaštitim dio koda koji mi je bio potreban, zamijenio sam mutex funkcije (sagrađene na vrhu mutex funkcionalnosti OS) s malim izvornim Ada mutex paketom za kontrolu pristupa mutex-a tom dijelu.

Ubacio sam ga u kod i izvršio test. Sedam sati kasnije kod je i dalje radio.

Moj kod je dostavljen Rational-u, gdje su ga kompajlirali, rastavili i provjerili da ne koristi isti pristup koji je korišten u problematičnim mutex funkcijama.

Ovo je bio najveći pregled koda u mojoj karijeri 🙂 Sa mnom je u prostoriji bilo desetak inženjera i menadžera, još deset ljudi je bilo na konferencijskom pozivu - i svi su pregledali oko 20 linija koda.

Kod je pregledan, nove izvršne datoteke su sastavljene i predate na formalno regresijsko testiranje. Nekoliko sedmica kasnije, test odbrojavanja je bio uspješan i raketa je poletjela.

Dobro, to je sve u redu, ali koja je poenta priče?

Bio je to apsolutno odvratan problem. Stotine hiljada linija koda, paralelno izvršavanje, preko desetak procesa u interakciji, loša arhitektura i loša implementacija, interfejsi za ugrađene sisteme i potrošeni milioni dolara. Nema pritiska, zar ne.

Nisam bio jedini koji je radio na ovom problemu, iako sam bio u centru pažnje dok sam radio portiranje. Ali iako sam to uradio, to ne znači da sam razumeo sve stotine hiljada linija koda, ili čak da sam ih pregledao. Kod i logove su analizirali inženjeri širom zemlje, ali kada su mi rekli svoje hipoteze o uzrocima kvara, trebalo mi je samo pola minuta da ih opovrgnem. A kada su me zamolili da analiziram teorije, proslijedio bih to nekom drugom, jer mi je bilo očigledno da ti inženjeri idu pogrešnim putem. Zvučiš drsko? Da, to je tačno, ali sam hipoteze i zahtjeve odbacio iz drugog razloga.

Shvatio sam prirodu problema. Nisam znao gde se to tačno dešava ni zašto, ali sam znao šta se dešava.

Tokom godina, stekao sam mnogo znanja i iskustva. Bio sam jedan od pionira korišćenja Ade i shvatio sam njene prednosti i nedostatke. Znam kako Ada runtime biblioteke rukuju zadacima i bave se paralelnim izvršavanjem. I razumijem programiranje niskog nivoa na nivou memorije, registara i asemblera. Drugim riječima, imam duboko znanje u svojoj oblasti. I koristio sam ih da pronađem uzrok problema. Nisam samo zaobilazio grešku, shvatio sam kako da je pronađem u veoma osetljivom runtime okruženju.

Takve priče o borbi sa kodom nisu baš zanimljive za one koji nisu upoznati sa karakteristikama i uslovima takve borbe. Ali ove nam priče pomažu da shvatimo šta je potrebno za rješavanje zaista teških problema.

Da biste riješili zaista teške probleme, morate biti više od programera. Morate razumjeti “sudbinu” koda, kako on stupa u interakciju sa svojim okruženjem i kako samo okruženje funkcionira.

A onda ćete imati svoju uništenu prazničnu sedmicu.

Nastaviti.

izvor: www.habr.com

Dodajte komentar