Folklór programátorov a inžinierov (1. časť)

Folklór programátorov a inžinierov (1. časť)

Toto je výber príbehov z internetu o tom, ako majú ploštice niekedy úplne neuveriteľné prejavy. Možno aj vy máte čo povedať.

Alergia auta na vanilkovú zmrzlinu

Príbeh pre inžinierov, ktorí chápu, že jasné nie je vždy odpoveď a že bez ohľadu na to, ako pritiahnuté za vlasy sa môžu zdať fakty, stále sú to fakty. Divízia Pontiac spoločnosti General Motors Corporation dostala sťažnosť:

Toto je druhýkrát, čo vám píšem, a neobviňujem vás, že ste neodpovedali, pretože to znie šialene. Naša rodina má tradíciu jesť zmrzlinu každý večer po večeri. Druhy zmrzlín sa zakaždým menia a po večeri si celá rodina vyberáme, ktorú zmrzlinu si kúpime, po ktorej idem do obchodu. Nedávno som si kúpil nový Pontiac a odvtedy sa moje cesty za zmrzlinou stali problémom. Vidíte, vždy keď si kúpim vanilkovú zmrzlinu a vrátim sa z obchodu, auto nenaštartuje. Ak prinesiem inú zmrzlinu, auto naštartuje bez problémov. Chcem sa spýtať vážnu otázku, nech to znie akokoľvek hlúpo: „Čo je na Pontiacu, že sa nespustí, keď prinesiem vanilkovú zmrzlinu, ale spustí sa ľahko, keď prinesiem inú príchuť zmrzliny?“

Ako si viete predstaviť, prezident divízie bol k listu skeptický. Pre každý prípad som však poslal inžiniera na kontrolu. Prekvapilo ho, že ho stretol bohatý, vzdelaný muž žijúci v nádhernej oblasti. Dohodli sa, že sa stretnú hneď po večeri, aby mohli ísť obaja do obchodu na zmrzlinu. V ten večer to bola vanilka, a keď sa vrátili k autu, už neštartovalo.

Inžinier prišiel ešte tri večery. Prvýkrát bola zmrzlina čokoládová. Auto naštartovalo. Druhýkrát bola jahodová zmrzlina. Auto naštartovalo. Na tretí večer požiadal o vanilku. Auto nenaštartovalo.

Z racionálneho uvažovania inžinier odmietol uveriť, že auto je alergické na vanilkovú zmrzlinu. Preto som sa dohodol s majiteľom auta, že bude pokračovať v návštevách, kým nenájde riešenie problému. A po ceste si začal robiť poznámky: zapisoval si všetky informácie, dennú dobu, druh benzínu, čas príchodu a návratu z obchodu atď.

Inžinier si čoskoro uvedomil, že majiteľ auta trávi menej času nákupom vanilkovej zmrzliny. Dôvodom bolo rozloženie tovaru v predajni. Vanilková zmrzlina bola najobľúbenejšia a uchovávala sa v samostatnej mrazničke v prednej časti obchodu, aby sa dala ľahšie nájsť. A všetky ostatné odrody boli v zadnej časti obchodu a nájsť tú správnu odrodu a zaplatiť zabralo oveľa viac času.

Teraz bola otázka pre inžiniera: prečo auto nenaštartovalo, ak od vypnutia motora uplynulo menej času? Keďže problémom bol čas, nie vanilková zmrzlina, inžinier rýchlo našiel odpoveď: bol to plynový zámok. Vyskytovalo sa to každý večer, ale keď majiteľ auta strávil viac času hľadaním zmrzliny, motor sa stihol dostatočne schladiť a ľahko naštartoval. A keď si muž kúpil vanilkovú zmrzlinu, motor bol ešte príliš horúci a plynový uzáver sa nestihol rozpustiť.

Morálka: Aj úplne šialené problémy sú niekedy skutočné.

Crash

Je bolestivé to zažiť. Ako programátor zvyknete obviňovať svoj kód prvý, druhý, tretí... a niekde na desaťtisícom mieste obviňujete kompilátor. A ďalej v zozname už obviňujete vybavenie.

Tu je môj príbeh o hardvérovej chybe.

Pre hru Crash Bandicoot som napísal kód na načítanie a uloženie na pamäťovú kartu. Pre takého samoľúbyho vývojára hier to bolo ako prechádzka ružovým sadom: myslel som si, že práca bude trvať niekoľko dní. Nakoniec som však kód ladil šesť týždňov. Po ceste som riešil ďalšie problémy, no každých pár dní som sa k tomuto kódu na pár hodín vracal. Bola to agónia.

Príznak vyzeral takto: keď uložíte aktuálne hranie hry a pristúpite na pamäťovú kartu, všetko takmer vždy prebehne v poriadku... Niekedy však bez zjavného dôvodu vyprší časový limit operácie čítania alebo zápisu. Krátky záznam často poškodí pamäťovú kartu. Keď sa hráč pokúsi zachrániť, nielenže sa mu nepodarí zachrániť, ale aj zničí mapu. Sakra.

Po chvíli náš producent v Sony, Connie Bus, začal panikáriť. Hru s touto chybou sme nemohli odoslať a o šesť týždňov neskôr som nechápal, čo spôsobuje problém. Prostredníctvom Connie sme oslovili ďalších vývojárov PS1: stretol sa niekto s niečím podobným? Nie Nikto nemal problémy s pamäťovou kartou.

Ak nemáte žiadne nápady na ladenie, zostáva jediným prístupom „rozdeľovať a panovať“: odstraňovať viac a viac kódu z chybného programu, kým nezostane relatívne malý fragment, ktorý stále spôsobuje problém. To znamená, že odrezávate program kúsok po kúsku, kým nezostane časť, ktorá obsahuje chybu.

Ide však o to, že je veľmi ťažké vystrihnúť kúsky z videohry. Ako ho spustiť, ak ste odstránili kód, ktorý emuluje gravitáciu? Alebo kreslenie postavičiek?

Preto musíme nahradiť celé moduly stubmi, ktoré predstierajú, že robia niečo užitočné, no v skutočnosti robia niečo veľmi jednoduché, čo nemôže obsahovať chyby. Musíme napísať také barličky, aby hra aspoň fungovala. Toto je pomalý a bolestivý proces.

Skrátka sa mi to podarilo. Odstraňoval som stále viac kúskov kódu, kým mi nezostal počiatočný kód, ktorý konfiguruje systém na spustenie hry, inicializuje vykresľovací hardvér atď. Samozrejme, v tejto fáze som nemohol vytvoriť menu uloženia a načítania, pretože by som musel vytvoriť stub pre celý grafický kód. Ale mohol by som predstierať, že som používateľ pomocou (neviditeľnej) obrazovky uloženia a načítania a požiadať o uloženie a zápis na pamäťovú kartu.

To mi zanechalo malý kúsok kódu, ktorý mal stále vyššie uvedený problém - ale stále sa to dialo náhodne! Väčšinou všetko fungovalo dobre, ale občas sa vyskytli chyby. Odstránil som takmer celý kód hry, ale chyba bola stále nažive. Bolo to zarážajúce: zostávajúci kód v skutočnosti nič nerobil.

V určitom okamihu, pravdepodobne okolo tretej ráno, ma napadla myšlienka. Operácie čítania a zápisu (vstup/výstup) zahŕňajú presné časy vykonávania. Keď pracujete s pevným diskom, pamäťovou kartou alebo modulom Bluetooth, nízkoúrovňový kód zodpovedný za čítanie a zápis to robí v súlade s hodinovými impulzmi.

Pomocou hodín sa zariadenie, ktoré nie je priamo spojené s procesorom, synchronizuje s kódom vykonávaným na procesore. Hodiny určujú prenosovú rýchlosť – rýchlosť, ktorou sa dáta prenášajú. Ak dôjde k zámene s časovaním, potom je zmätený aj hardvér alebo softvér alebo oboje. A to je veľmi zlé, pretože dáta sa môžu poškodiť.

Čo ak niečo v našom kóde zamieňa načasovanie? Skontroloval som všetko, čo s tým súvisí v kóde testovacieho programu a všimol som si, že sme nastavili programovateľný časovač v PS1 na 1 kHz (1000 tikov za sekundu). To je dosť veľa, štandardne pri spustení konzoly beží na 100 Hz. A väčšina hier používa túto frekvenciu.

Andy, vývojár hry, nastavil časovač na 1 kHz, aby sa pohyby počítali presnejšie. Andy má tendenciu ísť cez palubu, a ak napodobňujeme gravitáciu, robíme to čo najpresnejšie!

Čo ak však zrýchlenie časovača nejako ovplyvnilo celkové načasovanie programu, a teda hodiny, ktoré regulujú prenosovú rýchlosť pre pamäťovú kartu?

Komentoval som kód časovača. Chyba sa už neopakovala. To však neznamená, že sme to opravili, pretože porucha sa vyskytla náhodne. Čo keby som mal len šťastie?

O niekoľko dní neskôr som opäť experimentoval s testovacím programom. Chyba sa neopakovala. Vrátil som sa k plnej kódovej základni hry a upravil som kód uloženia a načítania tak, aby sa programovateľný časovač pred prístupom na pamäťovú kartu resetoval na pôvodnú hodnotu (100 Hz) a potom sa resetoval späť na 1 kHz. K zrážkam už nedošlo.

Ale prečo sa to stalo?

Opäť som sa vrátil k testovaciemu programu. Snažil som sa nájsť nejaký vzor vo výskyte chyby s 1 kHz časovačom. Nakoniec som si všimol, že chyba nastáva, keď sa niekto hrá s ovládačom PS1. Keďže by som to sám robil len zriedka – načo by som potreboval ovládač pri testovaní kódu uloženia a načítania? - Túto závislosť som si ani nevšimol. Jedného dňa však jeden z našich umelcov čakal, kým dokončím testovanie – asi som v tej chvíli nadával – a nervózne krútil ovládačom v rukách. Došlo k chybe. "Počkaj čo?!" Tak to zopakuj!"

Keď som si uvedomil, že tieto dve udalosti sú vzájomne prepojené, dokázal som chybu jednoducho zopakovať: začal som nahrávať na pamäťovú kartu, posunul som ovládač a zničil som pamäťovú kartu. Mne to pripadalo ako hardvérová chyba.

Prišiel som za Connie a povedal som jej o svojom objave. Informácie odovzdala jednému z inžinierov, ktorí navrhli PS1. "Nemožné," odpovedal, "to nemôže byť hardvérový problém." Požiadal som Connie, aby pre nás zorganizovala rozhovor.

Inžinier mi zavolal a dohadovali sme sa jeho lámanou angličtinou a mojou (extrémne) lámanou japončinou. Nakoniec som povedal: "Dovoľte mi poslať môj 30-riadkový testovací program, kde pohyb ovládača spôsobuje chybu." Súhlasil. Povedal, že je to strata času a že je strašne zaneprázdnený prácou na novom projekte, ale vzdal sa, pretože sme pre Sony veľmi dôležitý vývojár. Vyčistil som svoj testovací program a poslal som mu ho.

Nasledujúci večer (boli sme v Los Angeles a on v Tokiu) mi zavolal a hanblivo sa ospravedlnil. Išlo o hardvérový problém.

Neviem v čom presne bola chyba, ale čo som počul v centrále Sony, ak ste nastavili časovač na dostatočne vysokú hodnotu, rušilo to komponenty na základnej doske v blízkosti kryštálu časovača. Jedným z nich bol ovládač prenosovej rýchlosti pre pamäťovú kartu, ktorý zároveň nastavoval prenosovú rýchlosť pre ovládače. Nie som inžinier, takže som možno niečo pokazil.

Základom však je, že došlo k interferencii medzi komponentmi na základnej doske. A pri súčasnom prenose dát cez port radiča a port pamäťovej karty s časovačom bežiacim na 1 kHz sa stratili bity, dáta sa stratili a karta sa poškodila.

Zlé kravy

V osemdesiatych rokoch minulého storočia môj mentor Sergej napísal softvér pre SM-1980, sovietsky klon PDP-1800. Tento mikropočítač bol práve nainštalovaný na železničnej stanici neďaleko Sverdlovska, dôležitého dopravného uzla v ZSSR. Nový systém bol navrhnutý tak, aby smeroval vagóny a nákladnú dopravu. Obsahoval však nepríjemnú chybu, ktorá viedla k náhodným pádom a pádom. K pádom dochádzalo vždy, keď niekto šiel večer domov. Ale napriek dôkladnému vyšetrovaniu na druhý deň počítač fungoval správne vo všetkých manuálnych aj automatických testoch. Zvyčajne to naznačuje podmienku pretekov alebo inú konkurenčnú chybu, ktorá sa vyskytuje za určitých podmienok. Sergej, unavený z telefonátov neskoro v noci, sa rozhodol prísť tomu na koreň a v prvom rade pochopiť, aké podmienky na zoraďovacej stanici viedli k poruche počítača.

Najprv zozbieral štatistiky všetkých nevysvetliteľných pádov a vytvoril graf podľa dátumu a času. Vzor bol zrejmý. Po niekoľkých ďalších dňoch pozorovania si Sergej uvedomil, že dokáže ľahko predpovedať čas budúcich zlyhaní systému.

Čoskoro sa dozvedel, že k poruchám došlo len vtedy, keď stanica triedila vlaky dobytka zo severnej Ukrajiny a západného Ruska smerujúce na neďaleký bitúnok. Už to samo o sebe bolo zvláštne, pretože bitúnok zásobovali farmy, ktoré sa nachádzali oveľa bližšie, v Kazachstane.

Černobyľská jadrová elektráreň explodovala v roku 1986 a rádioaktívny spad spôsobil, že okolité oblasti boli neobývateľné. Kontaminované boli rozsiahle oblasti na severe Ukrajiny, Bieloruska a západného Ruska. Sergej, ktorý mal podozrenie na vysokú úroveň žiarenia v prichádzajúcich vagónoch, vyvinul metódu na testovanie tejto teórie. Obyvateľstvo malo zakázané mať dozimetre, a tak sa Sergej zaregistroval u niekoľkých vojakov na železničnej stanici. Po niekoľkých pohárikoch vodky sa mu podarilo presvedčiť vojaka, aby zmeral úroveň radiácie v jednom z podozrivých vozňov. Ukázalo sa, že hladina bola niekoľkonásobne vyššia ako normálne hodnoty.

Nielenže dobytok vyžaroval veľa žiarenia, jeho úroveň bola taká vysoká, že viedla k náhodnej strate bitov v pamäti SM-1800, ktorá bola umiestnená v budove vedľa stanice.

V ZSSR bol nedostatok potravín a úrady sa rozhodli miešať černobyľské mäso s mäsom z iných regiónov krajiny. To umožnilo znížiť celkovú úroveň rádioaktivity bez straty cenných zdrojov. Keď sa o tom Sergej dozvedel, okamžite vyplnil dokumenty na emigráciu. A pády počítača sa zastavili samy, keď sa úroveň radiácie časom znížila.

Cez potrubia

Kedysi spoločnosť Movietech Solutions vytvorila softvér pre kiná, určený na účtovníctvo, predaj vstupeniek a všeobecný manažment. Verzia hlavnej aplikácie pre DOS bola pomerne populárna medzi malými a stredne veľkými reťazcami kín v Severnej Amerike. Nie je teda prekvapujúce, že keď bola ohlásená verzia Windows 95, integrovaná s najnovšími dotykovými obrazovkami a samoobslužnými kioskami a vybavená všetkými druhmi nástrojov na vytváranie správ, rýchlo sa stala populárnou. Aktualizácia väčšinou prebehla bez problémov. Miestni IT pracovníci nainštalovali nové zariadenia, migrovali dáta a obchod pokračoval. Okrem prípadov, keď to nevydržalo. Keď sa to stalo, spoločnosť vyslala Jamesa, prezývaného „Čistič“.

Hoci prezývka naznačuje nekalý typ, upratovačka je len kombináciou inštruktora, inštalatéra a všeuměla. James strávil niekoľko dní u klienta zostavovaním všetkých komponentov a potom strávil ďalších pár dní učením personálu, ako používať nový systém, riešením akýchkoľvek problémov s hardvérom, ktoré sa vyskytli, a v podstate pomáhal softvéru v jeho začiatkoch.

Preto nie je prekvapujúce, že v týchto hektických časoch prišiel James ráno do kancelárie a skôr, ako sa dostal k svojmu stolu, privítal ho manažér naplnený kofeínom nad rámec obvyklého.

"Obávam sa, že musíte čo najskôr ísť do Annapolisu v Novom Škótsku." Celý ich systém vypadol a po noci strávenej prácou s ich inžiniermi nevieme prísť na to, čo sa stalo. Zdá sa, že sieť na serveri zlyhala. Ale až potom, čo systém bežal niekoľko minút.

— Nevrátili sa k starému systému? - odpovedal James úplne vážne, hoci v duchu prekvapene vytreštil oči.

— Presne tak: ich IT špecialista „zmenil priority“ a rozhodol sa odísť so svojim starým serverom. James, nainštalovali systém na šiestich miestach a len zaplatili za prémiovú podporu a ich podnikanie teraz funguje ako v 1950. rokoch minulého storočia.

James sa mierne narovnal.

- To je ďalšia vec. Dobre, začnime.

Keď prišiel do Annapolisu, prvá vec, ktorú urobil, bolo nájsť zákazníkovo prvé divadlo, ktoré malo problém. Na mape zhotovenej na letisku vyzeralo všetko slušne, no okolie želanej adresy vyzeralo podozrivo. Nie geto, ale pripomína film noir. Keď James zaparkoval pri obrubníku v centre mesta, pristúpila k nemu prostitútka. Vzhľadom na veľkosť Annapolisu bol s najväčšou pravdepodobnosťou jediný v celom meste. Jej vzhľad okamžite spomenul slávnu postavu, ktorá na veľkom plátne ponúkala sex za peniaze. Nie, nie o Julii Robertsovej, ale o Jonovi Voightovi [narážka na film "Polnočný kovboj" - cca. pruh].

Keď James poslal prostitútku na cestu, odišiel do kina. Okolie sa zlepšilo, ale stále pôsobilo spustnutým dojmom. Nie že by sa James príliš trápil. Už bol na úbohých miestach. A toto bola Kanada, kde sú dokonca aj zlodeji natoľko zdvorilí, že po vzatí peňaženky poďakujú.

Bočný vchod do kina bol vo vlhkej uličke. James podišiel k dverám a zaklopal. Čoskoro to zaškrípalo a mierne sa otvorilo.

-Vy ste upratovačka? - ozval sa zvnútra chrapľavý hlas.

- Áno, to som ja... prišiel som všetko opraviť.

James vošiel do haly kina. Zamestnanci, ktorí zrejme nemali inú možnosť, začali návštevníkom rozdávať papierové lístky. To sťažilo finančné výkazníctvo, nieto ešte zaujímavejšie detaily. Ale personál privítal Jamesa s úľavou a okamžite ho vzal do serverovne.

Na prvý pohľad bolo všetko v poriadku. James sa prihlásil na server a skontroloval obvyklé podozrivé miesta. Žiaden problém. James však z veľkej opatrnosti vypol server, vymenil sieťovú kartu a vrátil systém späť. Okamžite sa pustila do práce naplno. Personál opäť začal predávať lístky.

James zavolal Markovi a informoval ho o situácii. Nie je ťažké si predstaviť, že by James mohol chcieť zostať a zistiť, či sa nestane niečo neočakávané. Zišiel dole schodmi a začal sa zamestnancov vypytovať, čo sa stalo. Je zrejmé, že systém prestal fungovať. Vypli a zapli, všetko fungovalo. Ale po 10 minútach systém vypadol.

Práve v tejto chvíli sa stalo niečo podobné. Zrazu systém predaja lístkov začal vyhadzovať chyby. Personál si povzdychol a schmatol papierové lístky a James sa ponáhľal do serverovne. Všetko so serverom vyzeralo dobre.

Potom vstúpil jeden zo zamestnancov.

— Systém opäť funguje.

James bol zmätený, pretože nič neurobil. Presnejšie, nič, vďaka čomu by systém fungoval. Odhlásil sa, zdvihol telefón a zavolal na linku podpory svojej spoločnosti. Čoskoro ten istý zamestnanec vstúpil do serverovne.

- Systém nefunguje.

James pozrel na server. Na obrazovke tancoval zaujímavý a známy vzor rôznofarebných tvarov – chaoticky sa zvíjajúce a prepletajúce fajky. Všetci sme už niekedy videli tento šetrič obrazovky. Bolo to nádherne vykreslené a doslova hypnotizujúce.


James stlačil tlačidlo a vzor zmizol. Ponáhľal sa k pokladni a cestou stretol zamestnanca, ktorý sa k nemu vracal.

— Systém opäť funguje.

Ak dokážete urobiť mentálny facepalm, presne to urobil James. Šetrič obrazovky. Používa OpenGL. A preto počas prevádzky spotrebúva všetky zdroje procesora servera. Výsledkom je, že každé volanie na server končí časovým limitom.

James sa vrátil do serverovne, prihlásil sa a nahradil šetrič obrazovky krásnymi rúrami s prázdnou obrazovkou. To znamená, že namiesto šetriča obrazovky, ktorý spotrebuje 100% zdrojov procesora, som nainštaloval iný, ktorý zdroje nespotrebováva. Potom som čakal 10 minút, aby som skontroloval svoj odhad.

Keď James prišiel do ďalšieho kina, premýšľal, ako vysvetliť svojmu manažérovi, že práve letel 800 km, aby vypol šetrič obrazovky.

Havária počas určitej fázy mesiaca

Pravdivý príbeh. Jedného dňa sa objavila softvérová chyba, ktorá závisela od fázy mesiaca. Existovala malá rutina, ktorá sa bežne používala v rôznych programoch MIT na výpočet aproximácie skutočnej fázy Mesiaca. GLS zabudoval túto rutinu do programu LISP, ktorý pri zápise súboru vypíše riadok s časovou pečiatkou dlhou takmer 80 znakov. Bolo veľmi zriedkavé, že prvý riadok správy bol príliš dlhý a viedol k ďalšiemu riadku. A keď program neskôr čítal tento súbor, nadával. Dĺžka prvého riadku závisela od presného dátumu a času, ako aj od dĺžky špecifikácie fázy v čase vytlačenia časovej pečiatky. To znamená, že chyba doslova závisela od fázy mesiaca!

Prvé papierové vydanie Súbor žargónu (Steele-1983) obsahoval príklad takejto linky, ktorá viedla k opísanej chybe, ale sadzač ju „opravil“. Odvtedy sa to opísalo ako „chyba fázy mesiaca“.

Buďte však opatrní s predpokladmi. Pred niekoľkými rokmi sa inžinieri z CERNu (Európskeho centra pre jadrový výskum) stretli s chybami pri experimentoch uskutočnených na Veľkom elektrón-pozitrónovom urýchľovači. Keďže počítače aktívne spracovávajú obrovské množstvo údajov generovaných týmto zariadením predtým, ako výsledok ukážu vedcom, mnohí špekulovali, že softvér bol nejakým spôsobom citlivý na fázu mesiaca. Niekoľko zúfalých inžinierov prišlo na dno pravdy. Chyba vznikla miernou zmenou geometrie 27 km dlhého prstenca v dôsledku deformácie Zeme pri prechode Mesiaca! Tento príbeh vstúpil do fyzikálneho folklóru ako „Newtonova pomsta na časticovej fyzike“ a ako príklad spojenia medzi najjednoduchšími a najstaršími zákonmi fyziky a najpokročilejšími vedeckými konceptmi.

Spláchnutím toalety sa vlak zastaví

Najlepšia hardvérová chyba, o akej som kedy počul, bola vo vysokorýchlostnom vlaku vo Francúzsku. Chyba viedla k núdzovému brzdeniu vlaku, ale iba ak boli na palube cestujúci. V každom takomto prípade bol vlak vyradený z prevádzky, skontrolovaný, no nič sa nenašlo. Potom ho poslali späť na čiaru a okamžite zastavil.

Pri jednej z kontrol išiel strojník cestujúci vo vlaku na toaletu. Čoskoro zmyl, BUM! Núdzová zastávka.

Inžinier kontaktoval vodiča a spýtal sa:

— Čo si robil tesne pred brzdením?

- No, pri zostupe som spomalil...

Bolo to zvláštne, pretože počas bežnej prevádzky vlak spomaľuje v klesaniach desiatky krát. Vlak sa pohol ďalej a pri ďalšom klesaní rušňovodič varoval:

- Idem spomaliť.

Nič sa nestalo.

— Čo ste robili pri poslednom brzdení? - spýtal sa vodič.

- No... bol som na záchode...

- No, tak choď na záchod a urob to, čo si urobil, keď pôjdeme znova dole!

Inžinier odišiel na toaletu a keď vodič varoval: „Spomalím,“ spláchol vodu. Samozrejme, že vlak okamžite zastavil.

Teraz mohli problém reprodukovať a potrebovali nájsť príčinu.

Po dvoch minútach si všimli, že kábel diaľkového ovládania motorovej brzdy (vlak mal na každom konci jeden motor) je odpojený od steny elektrickej skrine a leží na relé, ktoré ovládalo solenoid zásuvkovej zástrčky... Keď relé bol zapnutý, rušil brzdový kábel a ochrana systému pred poruchami jednoducho zahŕňala núdzové brzdenie.

Brána, ktorá nenávidela FORTRAN

Pred niekoľkými mesiacmi sme si všimli, že sieťové pripojenia na pevnine [toto bolo na Havaji] sú veľmi, veľmi pomalé. Môže to trvať 10-15 minút a potom sa to náhle objaví znova. Po čase sa mi kolega sťažoval, že sieťové spojenia na pevnine vo všeobecnosti nefunguje. Mal nejaký FORTRAN kód, ktorý bolo potrebné skopírovať do stroja na pevnine, ale nešlo to, pretože „sieť nevydržala dostatočne dlho na to, aby sa dokončilo nahrávanie na FTP“.

Áno, ukázalo sa, že k zlyhaniam siete došlo, keď sa kolega pokúsil FTP súbor so zdrojovým kódom vo FORTRANe preniesť na stroj na pevnine. Pokúsili sme sa súbor archivovať: potom bol skopírovaný hladko (ale cieľový počítač nemal rozbaľovač, takže problém nebol vyriešený). Nakoniec sme "rozdelili" FORTRAN kód na veľmi malé kúsky a posielali sme ich jeden po druhom. Väčšina fragmentov bola skopírovaná bez problémov, ale niekoľko kusov neprešlo alebo prešlo početné pokusov.

Keď sme preskúmali problematické pasáže, zistili sme, že majú niečo spoločné: všetky obsahovali bloky komentárov, ktoré začínali a končili riadkami s veľkým C (ako kolega radšej komentoval vo FORTRANe). Poslali sme e-mailom sieťovým expertom na pevnine a požiadali sme o pomoc. Samozrejme, chceli vidieť vzorky našich súborov, ktoré nebolo možné preniesť cez FTP... ale naše listy sa k nim nedostali. Nakoniec sme prišli na jednoduchú vec popísaťako vyzerajú neprenosné súbory. Fungovalo to :) [Dovolím si sem pridať príklad jedného z problematických komentárov FORTRAN? Pravdepodobne to nestojí za to!]

Nakoniec sa nám to podarilo zistiť. Nedávno bola nainštalovaná nová brána medzi našou časťou kampusu a pevninskou sieťou. Mal OBROVSKÉ problémy s prenosom paketov, ktoré obsahovali opakované bity veľkého písmena C! Len niekoľko z týchto paketov by mohlo zabrať všetky prostriedky brány a zabrániť väčšine ostatných paketov prejsť. Sťažovali sme sa výrobcovi brány... a oni odpovedali: „Ach, áno, stretávate sa s chybou opakovaného C! Už o ňom vieme." Problém sme nakoniec vyriešili zakúpením novej brány od iného výrobcu (na obranu prvého, nemožnosť prenosu programov FORTRAN môže byť pre niekoho výhodou!).

Tvrdé časy

Pred niekoľkými rokmi, keď som pracoval na vytvorení ETL systému v Perle, aby sa znížili náklady na 40. fázu klinických skúšok, potreboval som spracovať asi 000 1 dátumov. Dvaja z nich testom neprešli. To ma príliš netrápilo, pretože tieto dátumy boli prevzaté z údajov poskytnutých klientom, čo bolo často, povedzme, prekvapujúce. Ale keď som skontroloval pôvodné údaje, ukázalo sa, že ide o dátumy 2011. januára 1 a 2007. januára 30. Myslel som si, že chyba je obsiahnutá v programe, ktorý som práve napísal, ale ukázalo sa, že je to už XNUMX rokov starý. Pre tých, ktorí nepoznajú softvérový ekosystém, to môže znieť záhadne. Kvôli dlhodobému rozhodnutiu inej spoločnosti zarábať peniaze mi môj klient zaplatil za opravu chyby, ktorú jedna spoločnosť zaviedla náhodou a druhá zámerne. Aby ste pochopili, o čom hovorím, musím hovoriť o spoločnosti, ktorá pridala funkciu, ktorá sa nakoniec stala chybou, ako aj o niekoľkých ďalších zaujímavých udalostiach, ktoré prispeli k záhadnej chybe, ktorú som opravil.

Za starých dobrých čias počítače Apple niekedy spontánne prestavili dátum na 1. január 1904. Dôvod bol jednoduchý: na sledovanie dátumu a času sa používali „systémové hodiny“ napájané z batérie. Čo sa stalo, keď vybila batéria? Počítače začali sledovať dátum podľa počtu sekúnd od začiatku epochy. Epochou sme mysleli referenčný pôvodný dátum a pre počítače Macintosh to bol 1. január 1904. A po vybití batérie sa aktuálny dátum nastavil na určený. Ale prečo sa to stalo?

Predtým Apple používal 32 bitov na uloženie počtu sekúnd od pôvodného dátumu. Jeden bit môže uložiť jednu z dvoch hodnôt - 1 alebo 0. Dva bity môžu uložiť jednu zo štyroch hodnôt: 00, 01, 10, 11. Tri bity - jedna hodnota z ôsmich: 000, 001, 010, 011, 100 , 101, 110, 111 atď. A 32 môže uložiť jednu z 232 hodnôt, to znamená 4 294 967 296 sekúnd. Pre dátumy Apple sa to rovnalo približne 136 rokom, takže staršie počítače Mac nedokážu spracovať dátumy po roku 2040. A ak sa batéria systému vybije, dátum sa nastaví na 0 sekúnd od začiatku epochy a dátum musíte nastaviť manuálne pri každom zapnutí počítača (alebo kým si nekúpite novú batériu).

Rozhodnutie Apple ukladať dátumy ako sekundy od epochy však znamenalo, že dátumy pred epochou sme nezvládli, čo malo ďalekosiahle následky, ako uvidíme. Apple predstavil funkciu, nie chybu. Okrem iného to znamenalo, že operačný systém Macintosh bol imúnny voči „chybe tisícročia“ (čo sa nedalo povedať o mnohých aplikáciách Mac, ktoré mali svoje vlastné dátumové systémy na obchádzanie obmedzení).

Pokračuj. Použili sme Lotus 1-2-3, „zabijakú aplikáciu“ od IBM, ktorá pomohla spustiť revolúciu PC, hoci počítače Apple mali VisiCalc, vďaka ktorému bol osobný počítač úspešný. Spravodlivo, ak by sa neobjavili 1-2-3, PC by sotva vzlietli a história osobných počítačov by sa mohla vyvíjať úplne inak. Lotus 1-2-3 nesprávne považoval rok 1900 za priestupný rok. Keď Microsoft vydal svoju prvú tabuľku, Multiplan, získal malý podiel na trhu. A keď spustili projekt Excel, rozhodli sa nielen skopírovať schému pomenovania riadkov a stĺpcov z Lotusu 1-2-3, ale tiež zabezpečiť kompatibilitu chýb tým, že schválne považovali rok 1900 za priestupný rok. Tento problém pretrváva dodnes. To znamená, že v 1-2-3 to bola chyba, ale v Exceli to bolo vedomé rozhodnutie, ktoré zabezpečilo, že všetci používatelia 1-2-3 mohli importovať svoje tabuľky do Excelu bez zmeny údajov, aj keď boli nesprávne.

Bol tu však ďalší problém. Po prvé, Microsoft vydal Excel pre Macintosh, ktorý neuznával dátumy pred 1. januárom 1904. A v Exceli bol 1. január 1900 považovaný za začiatok éry. Preto vývojári urobili zmenu, aby ich program rozpoznal typ éry a uložil v sebe dáta v súlade s požadovanou érou. Microsoft o tom dokonca napísal vysvetľujúci článok. A toto rozhodnutie viedlo k mojej chybe.

Môj ETL systém dostal od zákazníkov excelové tabuľky, ktoré boli vytvorené na Windowse, ale dali sa vytvoriť aj na Macu. Preto začiatok éry v tabuľke mohol byť buď 1. január 1900, alebo 1. január 1904. Ako to zistiť? Formát súboru Excel zobrazuje potrebné informácie, ale analyzátor, ktorý som použil, ich neukázal (teraz áno) a predpokladal, že poznáte epochu pre konkrétnu tabuľku. Pravdepodobne som mohol stráviť viac času porozumením binárneho formátu Excelu a odoslaním opravy autorovi syntaktického analyzátora, ale mal som toho pre klienta oveľa viac, takže som rýchlo napísal heuristiku na určenie epochy. Bola jednoduchá.

V Exceli môže byť dátum 5. júl 1998 reprezentovaný vo formáte "07-05-98" (zbytočný americký systém), "5. júl 98", "5. júl 1998", "5. júl-98" resp. nejaký iný formát, ďalší zbytočný formát (iróniou osudu, jeden z formátov, ktorý moja verzia Excelu neponúkala, bol ISO 8601). Avšak v tabuľke bol neformátovaný dátum uložený buď ako „35981“ pre epochu-1900 alebo „34519“ pre epochu-1904 (čísla predstavujú počet dní od epochy). Jednoducho som použil jednoduchý analyzátor na extrahovanie roku z naformátovaného dátumu a potom som použil analyzátor Excel na extrahovanie roku z neformátovaného dátumu. Ak sa obe hodnoty líšili o 4 roky, potom som vedel, že používam systém s epochou-1904.

Prečo som nepoužil formátované dátumy? Pretože 5. júl 1998 môže byť naformátovaný ako „Júl 98“ so strateným dňom v mesiaci. Dostali sme tabuľky od toľkých spoločností, ktoré ich vytvorili toľkými rôznymi spôsobmi, že bolo na nás (v tomto prípade na mne), aby sme dátumy určili. Okrem toho, ak to Excel zvládne, mali by sme to urobiť aj my!

Zároveň som narazil na 39082. Pripomeniem, že Lotus 1-2-3 považoval rok 1900 za priestupný rok a to sa verne opakovalo aj v Exceli. A keďže sa tým pridal jeden deň k roku 1900, mnohé funkcie na výpočet dátumu mohli byť pre tento deň nesprávne. To znamená, že 39082 mohlo byť 1. januára 2011 (v počítačoch Mac) alebo 31. decembra 2006 (v systéme Windows). Ak môj „parser roka“ extrahoval rok 2011 z naformátovanej hodnoty, potom je všetko v poriadku. Ale keďže analyzátor Excelu nevie, ktorá epocha sa používa, predvolene sa nastaví na epochu-1900 a vráti rok 2006. Moja aplikácia videla, že rozdiel bol 5 rokov, považovala to za chybu, zaprotokolovala to a vrátila neformátovanú hodnotu.

Aby som to obišiel, napísal som toto (pseudokód):

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 potom bolo všetkých 40 000 dátumov analyzovaných správne.

Uprostred veľkých tlačových úloh

Začiatkom osemdesiatych rokov pracoval môj otec v Storage Technology, dnes už neexistujúcej divízii, ktorá vytvárala páskové mechaniky a pneumatické systémy pre vysokorýchlostné podávanie pásky.

Prepracovali jednotky tak, aby mohli mať jednu centrálnu jednotku „A“ pripojenú k siedmim jednotkám „B“ a malý operačný systém v RAM, ktorý ovládal jednotku „A“, mohol delegovať operácie čítania a zápisu na všetky jednotky „B“.

Pri každom spustení jednotky „A“ bolo potrebné vložiť disketu do periférnej jednotky pripojenej k „A“, aby sa operačný systém načítal do jej pamäte. Bolo to mimoriadne primitívne: výpočtový výkon zabezpečoval 8-bitový mikrokontrolér.

Cieľovou skupinou pre takéto zariadenia boli spoločnosti s veľmi veľkými dátovými skladmi – banky, obchodné reťazce atď. – ktoré potrebovali vytlačiť veľa adresných štítkov alebo bankových výpisov.

Jeden klient mal problém. Uprostred tlačovej úlohy môže jedna konkrétna jednotka „A“ prestať fungovať, čo spôsobí zastavenie celej úlohy. Aby sa obnovila prevádzka disku, zamestnanci museli všetko reštartovať. A ak sa to stalo uprostred šesťhodinovej úlohy, tak sa stratilo obrovské množstvo drahého počítačového času a narušil sa harmonogram celej operácie.

Technici boli vyslaní z Storage Technologies. Ale napriek ich maximálnemu úsiliu nedokázali chybu reprodukovať v testovacích podmienkach: zdalo sa, že sa vyskytla uprostred veľkých tlačových úloh. Problém nebol v hardvéri, vymenili všetko, čo sa dalo: RAM, mikrokontrolér, disketovú mechaniku, všetky mysliteľné časti páskovej mechaniky – problém pretrvával.

Potom technici zavolali na centrálu a zavolali Experta.

Odborník schmatol stoličku a šálku kávy, posadil sa do počítačovej miestnosti – v tých časoch tam boli miestnosti vyhradené počítačom – a sledoval, ako personál radí do radu veľkú tlačovú úlohu. Odborník čakal, že dôjde k zlyhaniu – a stalo sa. Všetci sa pozreli na Experta, no on netušil, prečo sa to stalo. Nariadil teda, aby sa úloha znova zaradila do frontu a všetok personál a technici sa vrátili do práce.

Odborník si opäť sadol do kresla a začal čakať na zlyhanie. Prešlo asi šesť hodín a došlo k poruche. Expert opäť nemal žiadne nápady, okrem toho, že všetko sa stalo v miestnosti plnej ľudí. Prikázal reštartovať misiu, posadil sa a čakal.

Pri treťom neúspechu si Expert niečo všimol. K zlyhaniu došlo, keď personál vymenil pásky v cudzej jednotke. K poruche navyše došlo hneď, ako jeden zo zamestnancov prešiel cez určitú dlaždicu na podlahe.

Zvýšenú podlahu tvorili hliníkové dlaždice položené vo výške 6 až 8 palcov. Pod vyvýšenou podlahou viedli početné drôty od počítačov, aby niekto náhodou nestúpil na dôležitý kábel. Dlaždice boli položené veľmi tesne, aby sa pod vyvýšenú podlahu nedostali nečistoty.

Odborník si uvedomil, že jedna z dlaždíc bola zdeformovaná. Keď zamestnanec stúpil na jeho roh, okraje dlaždice sa odierali o susedné dlaždice. Odierali sa s nimi aj plastové časti, ktoré spájali dlaždice, čo spôsobovalo statické mikrovýboje, ktoré vytvárali rádiofrekvenčné rušenie.

RAM je dnes oveľa lepšie chránená pred vysokofrekvenčným rušením. Ale v tých rokoch to tak nebolo. Odborník si uvedomil, že toto rušenie narušilo pamäť a tým aj fungovanie operačného systému. Zavolal podpornú službu, objednal nové dlaždice, sám ich nainštaloval a problém zmizol.

Je príliv!

Príbeh sa odohral v serverovej miestnosti, na štvrtom alebo piatom poschodí kancelárie v Portsmouthe (myslím), v oblasti dokov.

Jedného dňa unixový server s hlavnou databázou havaroval. Reštartovali ho, ale on veselo padal znova a znova. Rozhodli sme sa zavolať niekomu z podpornej služby.

Podporný chlapík... Myslím, že sa volal Mark, ale na tom nezáleží... Nemyslím si, že ho poznám. Na tom nezáleží, naozaj. Zostaňme s Markom, dobre? Skvelé.

Takže o pár hodín neskôr prišiel Mark (z Leedsu do Portsmouthu to nie je ďaleko, viete), zapol server a všetko fungovalo bez problémov. Typická prekliata podpora, klient je kvôli tomu veľmi rozrušený. Mark si prezerá protokolové súbory a nenájde nič nevhodné. Takže Mark nastúpi späť do vlaku (alebo akýmkoľvek dopravným prostriedkom, ktorým prišiel, podľa toho, čo viem, mohla to byť chromá krava... každopádne, na tom nezáleží, dobre?) a vracia sa do Leedsu. deň.

V ten istý večer server znova spadne. Príbeh je rovnaký... server sa nedvíha. Mark sa snaží pomôcť na diaľku, ale klient nemôže spustiť server.

Ďalší vlak, autobus, citrónová pusinka alebo iné svinstvo a Mark je späť v Portsmouthe. Pozrite, server sa spúšťa bez problémov! Zázrak. Mark strávi niekoľko hodín kontrolou, či je všetko v poriadku s operačným systémom alebo softvérom a vydáva sa do Leedsu.

Približne v polovici dňa server spadne (upokojte sa!). Tentoraz sa zdá rozumné priviesť ľudí na hardvérovú podporu, aby server nahradili. Ale nie, asi po 10 hodinách to tiež padá.

Situácia sa opakovala niekoľko dní. Server funguje, spadne asi po 10 hodinách a nespustí sa ďalšie 2 hodiny. Skontrolovali chladenie, netesnosti pamäte, skontrolovali všetko, ale nič nenašli. Potom zrážky ustali.

Týždeň prešiel bezstarostne... všetci boli spokojní. Šťastný, kým to všetko nezačne znova. Obrázok je rovnaký. 10 hodín práce, 2-3 hodiny odstávky...

A potom niekto (myslím, že mi povedali, že táto osoba nemá nič spoločné s IT) povedal:

"To je príliv!"

Výkrik sa stretol s prázdnymi pohľadmi a niečí ruka pravdepodobne zaváhala pri bezpečnostnom volacom tlačidle.

"Prestáva to fungovať s prílivom."

Pracovníkom IT podpory by sa to zdalo byť úplne cudzím konceptom, pretože je nepravdepodobné, že si budú čítať Ročenku prílivu pri káve. Vysvetlili, že to nemôže nijako súvisieť s prílivom, pretože server fungoval týždeň bez porúch.

"Minulý týždeň bol príliv nízky, ale tento týždeň je vysoký."

Trochu terminológie pre tých, ktorí nemajú licenciu na jachtu. Príliv a odliv závisí od lunárneho cyklu. A keď sa Zem otáča, každých 12,5 hodiny gravitačná sila Slnka a Mesiaca vytvorí prílivovú vlnu. Na začiatku 12,5 hodinového cyklu je príliv, v strede cyklu odliv a na konci opäť príliv. Ale ako sa mení obežná dráha Mesiaca, mení sa aj rozdiel medzi odlivom a prílivom. Keď je Mesiac medzi Slnkom a Zemou alebo na opačnej strane Zeme (mesiac v splne alebo bez mesiaca), dostávame syzygynské prílivy – najvyššie prílivy a najnižšie odlivy. Pri polmesiaci dostávame kvadratúrne prílivy – najnižšie prílivy. Rozdiel medzi týmito dvoma extrémami sa výrazne znižuje. Lunárny cyklus trvá 28 dní: syzygický - kvadratúrny - syzygický - kvadratúrny.

Keď technikom vysvetlili podstatu prílivových síl, okamžite ich napadlo, že treba zavolať políciu. A celkom logické. Ale ukázalo sa, že ten chlap mal pravdu. O dva týždne skôr neďaleko kancelárie kotvil torpédoborec. Vždy, keď ju príliv zdvihol do určitej výšky, radar lode skončil na úrovni podlahy serverovne. A radar (alebo elektronické bojové vybavenie alebo iná vojenská hračka) spôsobil chaos v počítačoch.

Letová misia pre raketu

Mal som za úlohu preniesť veľký (asi 400 tisíc riadkov) riadiaci a monitorovací systém rakiet na nové verzie operačného systému, kompilátora a jazyka. Presnejšie povedané, od Solaris 2.5.1 po Solaris 7 a od Verdix Ada Development System (VADS), napísané v Ada 83, po systém Rational Apex Ada, napísaný v Ada 95. VADS kúpila spoločnosť Rational a jej produkt bol zastarané, hoci Rational sa pokúsil implementovať kompatibilné verzie balíkov špecifických pre VADS, aby uľahčil prechod na kompilátor Apex.

Traja ľudia mi pomohli jednoducho skompilovať kód. Trvalo to dva týždne. A potom som pracoval na svojom, aby systém fungoval. Stručne povedané, bola to najhoršia architektúra a implementácia softvérového systému, s akým som sa stretol, takže dokončenie portu trvalo ďalšie dva mesiace. Systém bol následne predložený na testovanie, ktoré trvalo ešte niekoľko mesiacov. Chyby, ktoré sa pri testovaní našli, som okamžite opravil, no ich počet rýchlo klesol (zdrojový kód bol produkčný systém, takže jeho funkčnosť fungovala celkom spoľahlivo, len som musel odstrániť chyby, ktoré vznikli pri adaptácii na nový kompilátor). Nakoniec, keď všetko fungovalo ako malo, som bol preradený do iného projektu.

A v piatok pred Dňom vďakyvzdania zazvonil telefón.

Štart rakety mal byť otestovaný asi o tri týždne a pri laboratórnych testoch odpočítavania bola postupnosť príkazov zablokovaná. V reálnom živote by to test prerušilo a ak by k zablokovaniu došlo v priebehu niekoľkých sekúnd po naštartovaní motora, došlo by v pomocných systémoch k niekoľkým nezvratným úkonom, ktoré by si vyžiadali dlhú – a drahú – pripravenosť rakety. Nezačalo by to, ale veľa ľudí by bolo veľmi naštvaných na stratu času a veľa, veľa peňazí. Nedovoľte, aby vám niekto povedal, že ministerstvo obrany míňa peniaze neuvážene – nikdy som sa nestretol so zmluvným manažérom, ktorý by neuviedol rozpočet na prvé alebo druhé miesto a potom na plán.

V predchádzajúcich mesiacoch bola táto výzva na odpočítavanie spustená stokrát v mnohých variáciách, len s niekoľkými menšími škytavkami. Pravdepodobnosť, že k tomu dôjde, bola teda veľmi nízka, no jej dôsledky boli veľmi významné. Vynásobte oba tieto faktory a pochopíte, že správy predpovedali mne a desiatkam inžinierov a manažérov zničený prázdninový týždeň.

A pozornosť bola venovaná mne ako osobe, ktorá portovala systém.

Rovnako ako u väčšiny systémov kritických z hľadiska bezpečnosti sa zaznamenávalo veľa parametrov, takže bolo pomerne jednoduché identifikovať niekoľko riadkov kódu, ktoré boli spustené pred zrútením systému. A samozrejme, nebolo na nich absolútne nič nezvyčajné, rovnaké výrazy boli úspešne vykonané doslova tisíckrát počas toho istého behu.

Zavolali sme ľudí z Apexu do Rational, pretože to boli oni, ktorí vyvinuli kompilátor a niektoré rutiny, ktoré vyvinuli, sa nazývali v podozrivom kóde. Na nich (a na všetkých ostatných) zapôsobilo, že je potrebné prísť na koreň problému doslova národného významu.

Keďže v časopisoch nebolo nič zaujímavé, rozhodli sme sa pokúsiť sa problém reprodukovať v miestnom laboratóriu. Nebola to ľahká úloha, pretože k udalosti došlo približne raz za 1000 jázd. Jedným z predpokladaných dôvodov bolo, že volanie funkcie mutex vyvinutej výrobcom (súčasť migračného balíka VADS) Unlock neviedlo k odomknutiu. Vlákno spracovania, ktoré zavolalo funkciu, spracovávalo správy srdcového tepu, ktoré nominálne prichádzali každú sekundu. Zvýšili sme frekvenciu na 10 Hz, teda 10-krát za sekundu, a začali sme bežať. Asi po hodine sa systém sám zablokoval. V protokole sme videli, že postupnosť zaznamenaných správ bola rovnaká ako pri neúspešnom teste. Urobili sme niekoľko ďalších jázd, systém bol dôsledne zablokovaný 45-90 minút po štarte a zakaždým, keď denník obsahoval rovnakú trasu. Aj keď sme technicky spúšťali iný kód – frekvencia správ bola iná – správanie systému bolo rovnaké, takže sme si boli istí, že tento scenár zaťaženia spôsobuje rovnaký problém.

Teraz sme potrebovali zistiť, kde presne došlo k blokovaniu v sekvencii výrazov.

Táto implementácia systému používala systém úloh Ada a používala ho neuveriteľne zle. Úlohy sú súbežne spustiteľný konštrukt na vysokej úrovni v Ada, niečo ako vlákna vykonávania, zabudované iba do samotného jazyka. Keď dve úlohy potrebujú komunikovať, „vytvoria stretnutie“, vymenia si potrebné údaje a potom stretnutie zastavia a vrátia sa k svojej nezávislej realizácii. Systém bol však implementovaný inak. Po stretnutí cieľovej úlohy sa táto cieľová úloha stretla s ďalšou úlohou, ktorá sa potom stretla s treťou úlohou, a tak ďalej, kým sa neukončilo nejaké spracovanie. Potom boli všetky tieto stretnutia dokončené a každá úloha sa musela vrátiť k svojej realizácii. To znamená, že sme mali do činenia s najdrahším systémom volania funkcií na svete, ktorý zastavil celý proces „multitaskingu“, kým spracovával časť vstupných dát. A predtým to neviedlo k problémom len preto, že priepustnosť bola veľmi nízka.

Tento mechanizmus úlohy som opísal preto, že keď sa požadovalo stretnutie alebo sa očakávalo jeho dokončenie, mohlo dôjsť k „prepnutie úlohy“. To znamená, že procesor by mohol začať spracovávať inú úlohu, ktorá je pripravená na vykonanie. Ukazuje sa, že keď je jedna úloha pripravená na stretnutie s inou úlohou, môže sa začať vykonávať úplne iná úloha a nakoniec sa riadenie vráti na prvé stretnutie. Môžu sa vyskytnúť aj ďalšie udalosti, ktoré spôsobia prepnutie úlohy; jednou z takýchto udalostí je volanie systémovej funkcie, ako je tlač alebo spustenie mutexu.

Aby som pochopil, ktorý riadok kódu spôsobuje problém, potreboval som nájsť spôsob, ako zaznamenať postup cez sekvenciu príkazov bez spustenia prepínača úloh, ktorý by zabránil zlyhaniu. Takže som to nemohol využiť Put_Line()aby ste sa vyhli vykonávaniu I/O operácií. Mohol by som nastaviť premennú počítadla alebo niečo podobné, ale ako môžem vidieť jej hodnotu, ak ju nemôžem zobraziť na obrazovke?

Pri skúmaní logu sa tiež ukázalo, že napriek zamrznutiu spracovania srdcových správ, ktoré blokovalo všetky I/O operácie procesu a znemožňovalo ďalšie spracovanie, sa naďalej vykonávali ďalšie nezávislé úlohy. To znamená, že práca nebola zablokovaná úplne, iba (kritický) reťazec úloh.

Toto bol kľúč potrebný na vyhodnotenie blokujúceho výrazu.

Vytvoril som balík Ada, ktorý obsahoval úlohu, vymenovaný typ a globálnu premennú tohto typu. Početné literály boli viazané na špecifické výrazy problematickej sekvencie (napr. Incrementing_Buffer_Index, Locking_Mutex, Mutex_Unlocked) a potom do nej vložili priraďovacie výrazy, ktoré priradili zodpovedajúci enumerácia globálnej premennej. Keďže objektový kód toho všetkého jednoducho ukladal konštantu do pamäte, prepínanie úloh v dôsledku jej vykonania bolo extrémne nepravdepodobné. Podozrievali sme predovšetkým výrazy, ktoré by mohli prepínať úlohu, pretože k zablokovaniu došlo pri vykonávaní a nie pri návrate pri prepínaní úlohy späť (z niekoľkých dôvodov).

Úloha sledovania jednoducho prebiehala v slučke a pravidelne kontrolovala, či sa zmenila hodnota globálnej premennej. Pri každej zmene sa hodnota uložila do súboru. Potom krátke čakanie a nová kontrola. Premennú som zapísal do súboru, pretože úloha bola vykonaná len vtedy, keď ju systém vybral na vykonanie pri prepínaní úlohy v problémovej oblasti. Čokoľvek sa stalo v tejto úlohe, neovplyvní ostatné, nesúvisiace zablokované úlohy.

Očakávalo sa, že keď systém dosiahne bod vykonania problematického kódu, globálna premenná sa pri prechode na každý ďalší výraz vynuluje. Potom sa stane niečo, čo spôsobí prepnutie úlohy a keďže jej frekvencia vykonávania (10 Hz) je nižšia ako pri monitorovacej úlohe, monitor by mohol zachytiť hodnotu globálnej premennej a zapísať ju. V normálnej situácii by som mohol získať opakujúcu sa sekvenciu podmnožiny enumerácií: posledné hodnoty premennej v čase prepnutia úlohy. Pri zavesení by sa globálna premenná už nemala meniť a posledná zapísaná hodnota bude indikovať, ktorý výraz sa nedokončil.

Spustil som kód so sledovaním. Zamrzol. A monitoring fungoval ako hodinky.

Protokol obsahoval očakávanú sekvenciu, ktorá bola prerušená hodnotou naznačujúcou, že bol zavolaný mutex Unlocka úloha nie je dokončená - ako je to v prípade tisícok predchádzajúcich hovorov.

Inžinieri Apexu v tom čase horúčkovito analyzovali svoj kód a našli miesto v mutexe, kde by teoreticky mohlo dôjsť k uzamknutiu. Jeho pravdepodobnosť však bola veľmi nízka, pretože k zablokovaniu mohla viesť iba určitá postupnosť udalostí vyskytujúcich sa v určitom čase. Murphyho zákon, chlapci, je to Murphyho zákon.

Aby som ochránil časť kódu, ktorú som potreboval, nahradil som volania funkcie mutex (vybudované nad funkciou mutex OS) malým natívnym balíkom Ada mutex na riadenie prístupu mutex k tomuto kusu.

Vložil som ho do kódu a spustil test. O sedem hodín neskôr kód stále fungoval.

Môj kód bol odoslaný spoločnosti Rational, kde ho skompilovali, rozobrali a skontrolovali, či nepoužíva rovnaký prístup, aký bol použitý v problematických funkciách mutexu.

Toto bola najpreplnená kontrola kódu v mojej kariére 🙂 V miestnosti so mnou bolo asi desať inžinierov a manažérov, ďalších desať ľudí bolo na konferenčnom hovore – a všetci skúmali asi 20 riadkov kódu.

Kód bol skontrolovaný, nové spustiteľné súbory boli zostavené a odoslané na formálne regresné testovanie. O pár týždňov neskôr bol test odpočítavania úspešný a raketa vzlietla.

Dobre, to je všetko dobré, ale aký je zmysel tohto príbehu?

Bol to absolútne odporný problém. Státisíce riadkov kódu, paralelné vykonávanie, viac ako tucet interagujúcich procesov, zlá architektúra a zlá implementácia, rozhrania pre vstavané systémy a vynaložené milióny dolárov. Žiadny tlak, správne.

Nebol som jediný, kto pracoval na tomto probléme, aj keď som bol v centre pozornosti, keď som robil portovanie. Ale aj keď som to urobil, neznamená to, že som porozumel všetkým stovkám tisíc riadkov kódu, alebo som ich dokonca preletel. Kód a protokoly analyzovali inžinieri po celej krajine, ale keď mi povedali svoje hypotézy o príčinách zlyhania, trvalo mi len pol minúty, kým som ich vyvrátil. A keď som bol požiadaný, aby som analyzoval teórie, odovzdal by som to niekomu inému, pretože mi bolo jasné, že títo inžinieri idú nesprávnou cestou. Znie to trúfalo? Áno, to je pravda, ale hypotézy a požiadavky som odmietol z iného dôvodu.

Pochopil som podstatu problému. Nevedel som presne, kde sa to deje a prečo, ale vedel som, čo sa deje.

Za tie roky som nazbieral množstvo vedomostí a skúseností. Bol som jedným z priekopníkov používania Ady a pochopil som jej výhody a nevýhody. Viem, ako runtime knižnice Ada zvládajú úlohy a riešia paralelné vykonávanie. A rozumiem nízkoúrovňovému programovaniu na úrovni pamäte, registrov a assembleru. Inými slovami, mám hlboké znalosti vo svojom odbore. A použil som ich na nájdenie príčiny problému. Neobchádzal som len chybu, ale pochopil som, ako ju nájsť vo veľmi citlivom runtime prostredí.

Takéto príbehy o boji s kódom nie sú veľmi zaujímavé pre tých, ktorí nie sú oboznámení s vlastnosťami a podmienkami takéhoto boja. Ale tieto príbehy nám pomáhajú pochopiť, čo je potrebné na vyriešenie skutočne zložitých problémov.

Ak chcete vyriešiť naozaj ťažké problémy, musíte byť viac ako len programátor. Musíte pochopiť „osud“ kódu, ako interaguje so svojím prostredím a ako funguje samotné prostredie.

A potom budete mať svoj vlastný zničený prázdninový týždeň.

Bude pokračovať.

Zdroj: hab.com

Pridať komentár