Bárkivel előfordul, hogy követ el hibákat munkahelyén. Ahogy mondani szokták: ahol fát gyalulnak ott hullik a forgács. Velünk, programozókkal sincs ez másként: néha elfelejtünk egy-egy sorvégi pontosvesszőt, különböző eseteket hagyunk figyelmen kívül, és még sorolhatnám.
Ezeket teszteléskor gyakran észrevesszük vagy észreveszi a tesztelő, de ha benne is maradnak a kódban sem mindig járnak katasztrofális következményekkel.
Máskor ezek a programkódban maradt hibák komoly biztonsági résként tátongva édesgetik magukhoz a jó- vagy rossz szándékú hackereket, akik így tetemes kárt is tehetnek az informatikai rendszerben. Ezekről gyakran beszélünk a Random Generátor Podcast adásaiban is, és olvashatjátok a hírekben.
Aztán vannak olyan hibák, amelyeknek ennél is súlyosabb következményei vannak. Ablakon kidobott dollár milliárdok, több évnyi tudományos kutató munka eredménye vagy akár emberéletek vesznek kárba egyetlen rosszul megírt kód miatt.
Ebben a bejegyzésben olyan programhibákat fogok bemutatni nektek, amelyek nem követeltek ember életeket, ellenben nagyon sok pénzbe kerültek a cégeknek. A halálos áldozatokat is követelő szoftverhibákról a második részben olvashattok.
Minden esetben átnézzük az eseményeket, majd hosszabb-rövidebb magyarázat közben kibontakoznak az eseményekhez vezető hibák.
Mars Climate Orbiter – 1998

Miután 1993-ban egy üzemanyag szivárgás miatt a NASA elvesztette a Mars Observer szondát, az űrügynökség egyből nekilátott pótolni azt. Ambiciózus tervet eszeltek ki az amerikaiak. A Nemzetközi Űrállomás költségeinek várható emelkedése miatt egy egy tonna alatti, olcsó, könnyen legyártható Mars-szondát szerettek volna megépíteni, lehetőleg minél gyorsabban.
A tervekből végül 1998-ra lett kézzel fogható eredmény: ez lett a Mars Surveyour 98 program, melynek keretén belül elkészült a Mars Polar Lander (rajta a két Deep Space 2 szondával) illetve a Mars Climate Orbiter.
Utóbbi egy alig 638kg-os, 2.1méter magas, 1.6 méter széles és 2 méter hosszú szerkezet volt, melynek egyik fő feladata a marsi légkör és időjárás tanulmányozása lett volna. A másik feladata pedig, hogy átjátszó állomásként szolgált volna a Polar Lander számára.
1998. december 11-én UTC idő szerint 18:45:51-kor a Mars Climate Orbiter-t szállító Delta 2 hordozórakéta megkezdte a felszállást Cape Canaveral-ból. 42 perccel később a manőver sikeresen véget ért, és a szonda a megfelelő pályára állt.
Ekkor az irányítóközpontban még mindenki nagyon boldog volt, és reménykedtek a küldetés sikerében. Kilenc és fél hónappal később elérte a Marsot az űrszonda, és ezzel újabb kritikus ponthoz érkezett a küldetés.
1999. Szeptember 23-án UTC idő szerint 09:00:46-kor megkezdődött a pályára állási manőver. Alig 5 perccel később a szonda eltűnt a Mars mögött, és beállt a tervezett rádiócsend. Az irányítóteremben mindössze azt furcsállták, hogy ez 42 másodperccel hamarabb történt meg, mint ahogy arra számítottak. A rádiókapcsolatot azonban ezután soha nem tudták felvenni a szondával.
Mi történt?
Az 1999-ben lezárult vizsgálat azt találta, hogy a bár az irányítók is hibáztak. Rosszul számolták a pályamagasságot, és így sokkal alacsonyabb pályára állították a szondát, mint az megengedhető lett volna.

Az emberi tényezőn kívül azonban az irányítószoftverben is volt egy kritikus hiba, ami nem jött elő a rendszerek tesztelésénél. A NASA a Lockheed Martin-nal közösen fejlesztette a szondát, és annak vezérlőszoftverét, amiben banális hibát vétettek a szakemberek.
A Lockheed Martin által fejlesztett programrész ugyanis angolszász mértékegységeket használt, míg a NASA által fejlesztett SI mértékegységben várta az eredményt. Konkrétan tehát az történt, hogy amikor a szoftvernek a pályára álláshoz szükséges tolóerőt kellett volna kiszámítani, a Lockheed Martin által fejlesztett rész font/másodpercben adta ki az értéket, míg a NASA szoftverrésze ezt newton/másodpercnek vette. 1 font/sec 4,5 newton/sec, ez azért elég tetemes különbség.
A NASA végül nem marasztalt el senkit, mivel elismerték, hogy nem volt megfelelően letesztelve a szoftver bevetés előtt.
Aztán ne felejtsük el, hogy a Deep Space 2 űrszondák is csúfos véget értek ugyanebben az évben. Így az 1999-es év nem volt épp a NASA éve.
A programhiba úgy nagyjából 460millió dollárjába került a NASA-nak, és nagyban hozzájárult a későbbi évek megszorításaihoz és a Mars-küldetések befagyasztásához.
Mariner I -1962

1962. július 28-án első próbarepülésére indult a Mariner I. Ám nem sokkal a fellövést követően a rakéta irányítószoftverében maradt bug miatt az iránytók kénytelenek voltak az Atlanti-óceán felett felrobbantani az irányíthatatlanná vált szerkezetet.
Mi történt?
Későbbi vizsgálatok megállapították, hogy többek között egy kézzel írt matematikai egyenletet nem sikerült jól átvinni gépi kóddá. A képen látható, hogy egyetlen felső vonal hiányzott csupán, ez azonban teljesen megváltoztatta a program viselkedését.

Eredetileg az azt jelentené, hogy az n-dik kiegyenlített értéke az R-el jelölt értéknek. Azonban a felső vonal hiánya miatt a kapott érték változása jóval nagyobbnak mutatkozott a rendszerben. Emiatt aztán pályát tévesztett a szerkezet.
Az űrszonda fellövéséhez használt Atlas hordozórakétát két radarrendszer irányította. A Rate System-nek nevezett rendszer figyelte a rakéta emelkedését a légkörön keresztül. A Track System a Cape Canaveral-ban található állomástól mért távolságot és szöget követte nyomon.
A két radarról érkező jeleket a központi számítógép dolgozta fel, és küldte tovább az irányítórendszernek, majd közvetítették tovább a rakétának.
A radarokról érkező jelekben azonban volt egy 43 milliszekundumnyi különbség. Így a számítógépet arra utasították, hogy a Rate System-ből érkező jelekhez, indításkor automatikusan adja hozzá a 43 milliszekundumot. Ezáltal a két rendszerről érkező adatok azonos időben érkeztek a központi számítógéphez.
Ehhez a művelethez a figyelt értékeket (sebesség, gyorsulás, stb-) el kell “simítani”, átlagolni kell. A felső vonal erre szolgált volna. Mivel azonban ez lemaradt, az irányításért felelős számítógép végig a nyers sebesség adatokkal dolgozott. Az így tovagyűrűző számítási pontatlanság nagyon hamar elérte azt a kritikus pontot, ahol egyszerűen már nem voltak értelmezhetők az adatok.
Az űrszonda lezuhanásához az is hozzájárult, hogy a rakéta más részegységei sem működtek megfelelően, ám a hiányzó felső vonást jelölték meg a legkritikusabb hibának. Az anyagi kár olyan 15-18millió dollár körül lehetett, ami mai árfolyamon durván 134millió dollárnak felelne meg.
Így talán nyugodtan nevezhetjük ezt a legdrágább elgépelésnek.
További érdekesség, hogy a Phobos-1 űrszonda is hasonlóan járt. Igaz ott nem a szoftverrel volt gond, hanem a földről küldött paranccsal. Akkor egy elmaradt kötőjel okozta a szonda elvesztését.
Ariane-5 – 1996

Egy másik, szintén az űr meghódítására tett csúfos kísérlet az Európai Űrügynökség nevéhez kötődik. 1996 június 4-én beindították az első Ariane-5 rakéta hajtóműveit Francia Guyana partjainál, mely közel tízévnyi fejlesztés, és többszáz millió euró elköltésének első próbája volt.
A felszállás után 37 másodperccel a rakéta erős 90fokos fordulatot vett, majd önmegsemmisítő módba kapcsolva elégett a légkörben.
A mérnökök nem értették a dolgot, hiszen a mérőműszerek nem jeleztek semmilyen rendellenességet. Papíron mindennek flottul kellett volna mennie az új, nagy teherbírású rakétageneráció fellövésénél, de mégsem ez történt.
Mi történt?
Későbbi vizsgálatok kiderítették a probléma okát: egy, az Ariane-4 szoftveréből hátramaradt kódsor okozott gondot.
A képen látható kódsor egy 64bites lebegőpontos számot alakít át egy 16bites előjelnélküli integerré, mely a műhorizont meghatározásához szükséges értéket tárol el. Ennek kiszámításához a rakéta aktuális sebességét is felhasználja. Csakhogy az átalakítás során probléma lépett fel.

16 bites előjel nélküli integer esetén a maximális érték 65.535, ha ennél nagyobb értéket szeretnénk benne tárolni, akkor túlcsordul. Ilyen esetben azonban nem lehet megmondani, hogy hogyan fog viselkedni a kód.
A probléma itt abból állt, hogy az Ariane-5 kevésbé meredek pályán mozgott, mint elődje, és erősebb is volt annál, így nagyobb sebességet tudott elérni. Amikor átlépte a sebességhatárt, a processzor a konvertálás során túlcsordult. Értelmezhetetlen adatokat generált, és így a rakéta inkább önmegsemmisítő módba kapcsolt.
A programot eredetileg az Ariane-4-hez írták, Ada nyelvben, és több hasonló konvertálás is történik a futása során. Összesen öt hasonló kódrészletet találtak a vezérlőszoftverben: hármat levédtek a fejlesztők, a másik kettőről úgy gondolták, hogy fizikai képtelenség elérni azt a sebességet, amit a számoláshoz felhasználva aztán túlcsordul a változó.
Nos ez mégis sikerült a rakétának. Külön érdekesség, hogy a hibás kódrészlet nem szükséges az Ariane-5 működéséhez, mivel más számítások alapján azt már korábban meghatározta.
Az Ariane rakétaprogramot nem állították le, hanem teljesen újratervezték a rakétákat. Valamint vezérlőprogramot is újraírták az elejéről, teljesen kukázva az Ariane-4 hagyatékát.
Hiába, néha csak a teljes refaktorálás segít.
Los Angeles-i repülőtér – 2004

Szintén a fejlesztői hanyagság, és a “Nem gondoltam volna” mentalitás vezetett egy súlyos problémához. 2004. szeptember 14-én Csendes-óceáni idő szerint délután 5 órakor.
A Los Angeles-i légi forgalmi irányítók közel 800 repülőgéppel vesztették el a rádiókapcsolatot egyik pillanatról a másikra. Eléggé ijesztő lehetett a helyzet, hiszen alig 3 évvel vagyunk a szeptember 11-i terrortámadások után.
A kommunikációs csatornák megszűnésével gyakorlatilag a pilóták, valamint a repülőterek alkalmazottainak lélekjelenléte, illetve a repülőkre szerelt ütközést megelőző (TCAS) rendszerek kellettek ahhoz, hogy ne legyen tömegkatasztrófa.
Ha 10-15 évvel korábban történik hasonló, amikor nem volt elterjedt az ütközés érzékelő a repülőkön, rengeteg ütközés történt volna a levegőben, több száz vagy ezer ember halálát okozva.
Mi okozott problémát?
A Voice Switching and Control System (VSCS) újraindult, amikor az újraindítás nem sikerült, akkor a backup rendszer is elhasalt, majd a teljes rádiókapcsolat megszűnt.
A hivatalos vizsgálat emberi hibát állapított meg. Az előírás szerint 30 naponta újra kellett volna indítani a Voice Communication System Upgrade (VSCU) alrendszert. Ennek feladata, hogy bizonyos időközönként megvizsgálja a VSCS állapotát, és dönt az újraindításáról illetve a backup rendszer felállításáról. Ez nem történt meg, és a rendszer felmondta a szolgálatot.
Azonban volt itt egy súlyos szoftveres probléma is. A VSCU milliszekundomonként számolt vissza 2 a 32 hatványáról, ami 4 milliárd millisecet jelent.
Ahhoz hogy onnan visszaszámolva 0-ig jusson a rendszer 50 napra volt szükség. Tehát ha 30 naponta újraindították, akkor soha nem kellett volna elérnie a 0-t.
Csakhogy a fejlesztő, éppen emiatt úgy gondolta, hogy nem védi le a 0-hoz érés esetét. A VSCU az ominózus napon elérte a 0-t, majd nem tudott tovább visszaszámolni. Emiatt nem tudta, hogyan kellene tovább futnia, ezért leállt.
Általánosan bevett gyakorlat, hogy ilyen esetekben nem engedjük elérni az adott értéket. Még azelőtt automatikusan reseteljük az értékeket, hogy komolyabb baj történne.
Szerencsére emberéleteket nem követelt a hiba. Viszont rengeteg járat kimaradt, rengeteg utas rekedt a reptereken, vagy kényszerült máshol leszállni, és megoldani az utazást. Ezenkívül rengeteg kártérítést kellett fizetni az utasok részére és a légitársaságok részére egyaránt.
AT&T -1990
Az amerikai telekommunikációs szolgáltató cég embereinek 1990. január 15-én volt nagyon rossz napja, amikor 9 órán keresztül voltak lehalva a nagy távolságú telefonvonalak. Egy szoftverfrissítésben maradt hiba miatt álltak a vonalak, melynek végeredménye: 60millió dollár veszteség (mai árfolyamon kb 120millió dollár), 75 millió nem kapcsolt hívás, 200 000 foglalás és egyéb üzleti célú telefonhívás kimaradása.
Ahhoz, hogy megértsük mi történt, kicsit érdemes beleásni magunkat az akkori hálózat működésébe. Az AT&T hálózatában a switcheknek nevezett egységek dolgozták fel a hívásokat. 1990-ben összesen 114 db 4ESS típusú switch működött az országban. A switchek képesek voltak magukat és a szomszédos switcheket is újraindítani, szoftveresen javítani, gyakorlatilag emberi beavatkozás nélkül működtek, és csak nagyon kritikus helyzetben kellett az emberi segítség. Mondhatjuk tehát, hogy egy nagyon fejlett rendszerről volt szó akkoriban.

A szoftver frissítés előtt ha egy switch leállt (legyen Switch 1), mert éppen újraindult vagy egyéb problémát észlelt, akkor kiküldött egy üzenetet, hogy “Bocs srácok, de én kidőltem, vigyétek ti a melót”. A szomszédos switch-ek újraindultak, így nem kommunikáltak a lehalt switch-el. Ha a Switch 1 helyreállt, akkor újabb üzenetben tudatta a szomszédos switch-ekkel, hogy újra elérhető, készen áll a hívások fogadására. A szomszédos switch-ek újraindultak, hogy tudjanak kommunikálni Switch 1-el, és minden ment tovább.
Az AT&T szakemberei azonban úgy találták, hogy ez túlságosan lassú, ezért nemes egyszerűséggel kivették a visszaállásról szóló üzenetet, így a lehalt switch újraindulás után azonnal elkezdte a hívások feldolgozását és ugyanúgy kommunikált a többi switch-el, mintha mi sem történt volna. A fejlesztéstől gyorsabb reset időt, és így gyorsabb működést vártak.
Csakhogy a kód hibás volt.
Itt láthatjátok a pszeudokódját az akkori frissítésnek. A probléma egy switch ágban elhelyezett if-ben lévő break volt, mely kiléptette a teljes switch ágból a programot.

Amikor az aminózus napon lehalt az egyik switch New York-ban, az kiküldte a jelet a szomszédos switcheknek, hogy ő nem tud hívásokat fogadni. Néhány milliseccel később egy újabb üzenetet küldött, ami viszont teljesen értelmezhetetlen volt a többi switch számára, így az újraindult. Ez a switch is kiküldte a túltelítettségi jelet a szomszédos switchnek, ami resetelődött ennek hatására, de az újabb üzenet azt is összezavarta. És ez így terjedt tovább a hálózaton, mind a 114 switch-en, amelyek egymásnak küldözgették felváltva a túltelítettségi jelet és az értelmezhetetlen üzenetet egymás után 9 órán keresztül.
A szakemberek végül downgradelték a szoftvert, az előző állapotra, és így szüntették meg a hibát.
Források
http://edition.cnn.com/TECH/space/9909/30/mars.metric.02/
https://index.hu/tech/szoftver/bug080807/
https://en.wikipedia.org/wiki/Ariane_5#Notable_launches
https://www.bugsnag.com/blog/bug-day-ariane-5-disaster
http://www.cse.psu.edu/~gxt29/bug/localCopies/airTraffic/airTraffic.htm
http://www.raketaezred.hu/index.php/hirek/szakmai-hirek/237-patriot-hiba-a-celt-teveszt-raketa
http://www.phworld.org/history/attcrash.htm
https://arstechnica.com/civis/viewtopic.php?t=862715