Razvoj visoko pouzdanog softvera: lov na lude slučajnosti

U onim rjeđim, ali u pravilu vrlo bitnim slučajevima, kada je pouzdanost rada softvera od maksimalne važnosti, njegov razvoj u obzir treba uključivati razne neobične koincidencije i probleme

Oton Ribić srijeda, 31. ožujka 2021. u 00:00

Spomenete li nekome u današnja vremena sigurnost softvera, obično će bez mnogo premišljanja pretpostaviti kako govorite o sigurnosti od malicioznih napada. No jedan drugi vid sigurnosti, i to sigurnost njegova izvođenja, u određenim je situacijama barem podjednako bitna. Raznim organizacijama poput bolnica, policije, banaka, osiguranja, vojske ili avijacije nije dovoljno biti siguran od napada, već i znati da se u svoj softver općenito mogu pouzdati. Štoviše, kod određenih vrsta proizvoda, primjerice, medicinskih uređaja, to je najviši prioritet uopće.

Na prvi pogled, ova tema može djelovati pomalo isprazno, jer – program ili radi ili ne radi. Jednom kad je softver implementiran kako treba, i testovi su pokazali kako i u teoriji i u praksi radi ono što se od njega očekuje, što drugo uopće može stvoriti probleme? Ne samo da takvih prikrivenih problema ima, nego ih postoji čitav spektar – a ovaj put pozabavit ćemo se nekim češćima i interesantnijima.

Nikad dovoljno bitova!

Krenimo od jednog povijesno notornog slučaja u programerskoj struci, koji je izazvao razne nevolje kad se o njemu nije razmišljalo: nepreciznosti brojeva s pomičnim zarezom. Naime, radi samog sustava njihova spremanja u memoriji, koji im dodjeljuje određeni broj bitova, oni se ne mogu pohraniti beskonačnom točnošću, a mnogi često korišteni brojevi, uključivo sveprisutni π, a i razne druge iracionalne brojeve, mnoge razlomke itd., traže beskonačno mnogo bitova za njihov točan oblik u znamenkama – binarnim, dekadskim ili bilo kojim drugim.

Stoga, ono što računala u tom slučaju memoriraju i računaju, samo su aproksimacije. Ovisno o raspoloživom broju bitova, one mogu biti manje ili više precizne, ali i dalje su – aproksimacije. Naravno, odstupanja radi ovog efekta ekstremno su sitna, i u većini se slučajeva mirno mogu zanemariti (ako računate opseg orbite Mjeseca, ne zanima vas greška od nekoliko centimetara), ali ne u svima. Specifične vrste proračuna koje ponavljaju velik broj operacija na istom broju sklone su potencirati taj problem, ili kolokvijalnije rečeno, “gomilati” grešku kroz svaki od milijuna koraka, nakon čega ona postaje itekako bitna.

S pozitivne strane, to je toliko široko podučavan problem, a računala toliko obiluju radnom memorijom, da danas više nije velik problem koristiti nešto više memorije i memorirati brojeve toliko precizno da se greška “suzbije” na prihvatljiv red veličine. Zbog toga danas nije više toliko izražen koliko u vremenima kad je svaki bajt bio dragocjen.

Druga metoda je koristiti “prave” razlomke – primjerice, umjesto memoriranja jedne trećine kao 0.33333 s ograničenim brojem znamenki, memorirati posebno cijele brojeve 1 i 3 (brojnik i nazivnik), te sve operacije izvoditi na taj, inherentno precizan način računanja s razlomcima. No taj pristup niti je svuda primjenjiv, niti je hardverski učinkovit.

Bolnički sustavi dobar su primjer softvera koji možda ne mora imati milijun mogućnosti, ali te koje ima, moraju biti višestruko redundantno točne
Bolnički sustavi dobar su primjer softvera koji možda ne mora imati milijun mogućnosti, ali te koje ima, moraju biti višestruko redundantno točne

Opasnost iz svemira

Softver maksimalne pouzdanosti u obzir mora uzimati i druge hardverske efekte. Već neko vrijeme poznato je da kozmička zračenja povremeno mogu nasumično “pogoditi” memorijski sklop računala i promijeniti mu sadržaj, tj. prebaciti određeni bit iz nule u jedinicu ili obrnuto. To nipošto nije čest slučaj, ali nije niti toliko ekstremno rijedak – praksa se “vrti” oko nekoliko slučajeva godišnje za memoriju reda veličine nekoliko gigabajta. Kako tome doskočiti kod izuzetno bitnih procesa, primjerice, bankovnih uplata ili, još osjetljiviji primjer, softvera koji automatski dozira lijek pacijentima?

Uzevši u obzir da nasumično promijenjeni bit memorije može utjecati na sve i svašta, uključivo poziciju izvršavanja u programu, ovdje se u pravilu izbjegavaju bilo kakvi kompromisi: svaka se varijabla skladišti dvostruko, svaki izračun obavlja dvaput (svaki u svojem nezavisnom procesu), i naposljetku uspoređuje rezultat. Ako nije jednak, proces se zaustavlja i notificira korisnik, ili sve započinje iznova. Tamo gdje se korisnik ne može time baviti, može se izvesti trostruki proces te u slučaju da jedan odstupa, pretpostaviti da su preostala dva identična točna. U takvim situacijama, iznimno neučinkovito korištenje hardvera smatra se prihvatljivim kako bi se osigurala pouzdanost rezultata.

Tuneli, baterije i naprasni prekidi

Nova vremena donijela su i nove brige na tom području: koliko god nam smartfoni olakšali milijun stvari, pošteno su izmučili i razvojne timove koji se bave visoko pouzdanim softverima za njih. Dok je kod konvencionalnih računala pitanje bilo – što će se dogoditi ako nestane struje (a što se kod osjetljivih računala rješava i sustavima za neprekidno napajanje), kod mobilne tehnologije otvaraju se razna teška pitanja. Što ako korisnik usred korištenja neke osjetljive aplikacije (primjerice, obavljanja transakcije u mobilnom bankarstvu) ostane bez GSM signala? Ili se isprazni baterija? Ili primi telefonski poziv, ili možda operacijski sustav prisilno ugasi aplikaciju radi velike potrošnje energije?

Radi svih tih mogućih koincidencija, rijetkih ali potencijalno štetnih, takvi softveri u pozadini imaju čitavu šumu logike koja se brine za njih. Komunikacija između uređaja i servera sastoji se od višekratnih poziva i odgovora, koji svi moraju proći prema planu kako bi se obostrano potvrdilo, primjerice, da je transakcija odobrena i provedena. Ali ako nije – potrebno je utvrditi gdje je zapela, postoji li rizik da se neželjeno izvede dvaput, i kako nastaviti: pauzirati ili opozvati sve dosad obavljeno?

Štoviše, otkad su kupnja i plaćanje preko Interneta postali normalna stvar, osobito tamo gdje treba uskladiti kupca, prodavatelja, banku, kartičnu kuću, izdavatelja certifikata i još tko-zna-koliko strana, ta kompleksna tematika postala je praktički neizbježna za bilo kakav oblik elektroničkog poslovanja. Drugim riječima, nakon što negdje kliknete tipku Confirm Purchase, u pozadini se provede i razmijeni masa provjera, naloga, potvrda o uspješnosti i potvrda uspješnog primitka, sve kako bi se osiguralo od toga da bilo koje dvije strane izgube komunikacijski kanal, ili se iznenadno ugase, ili nešto slično – a na krajnju štetu neke od uključenih strana.

Kod uređaja upravljanih računalima, poput industrijskih robota, softver s obje strane mora biti dovoljno predostrožan da ostane otporan na “prekidajući” kabel ili slične mehaničke i kemijske efekte
Kod uređaja upravljanih računalima, poput industrijskih robota, softver s obje strane mora biti dovoljno predostrožan da ostane otporan na “prekidajući” kabel ili slične mehaničke i kemijske efekte

Ni kabelu se ne može vjerovati

Inače, problematika seže šire od samog računala: periferni hardver koji je u situaciji napraviti poveći kaos (primjerice, kontroler motoriziranih robota u tvornici) slijedi slične principe. Ako se ta periferija za komunikaciju s računalom oslanja na vlastiti protokol, on mora biti pažljivo osmišljen, s čitavom šumom redundancija u softverima s obje strane.

Klasični primjer su industrijske okoline, gdje korozija kontakata i oštećenje kabela nisu ništa neuobičajeno. Protokoli i softver u tom su slučaju dizajnirani tako da se bilo koja instrukcija nikad ne može pogrešno protumačiti ako se bilo koje dvije ili tri žile kabela kratko spoje, ili, pak, ako bilo koja od njih počne “prekidati”. Još su prvi inženjeri koji su se počeli baviti digitalnom komunikacijom u prvoj polovici 20. stoljeća, shvatili da čak i najpouzdanija oprema prije ili kasnije postane podložna takvim hardverskim problemima, te umjesto da je nerazumno poboljšavaju (što vodi i u nerazumnu cijenu), preusmjerili su trud na učinkovitu detekciju i ispravljanje grešaka na softverskoj strani. Kao i u prethodnim slučajevima, to u pravilu rezultira značajnim povećanjem samog prometa podataka, ali to je cijena maksimalno pouzdane komunikacije.

Vratolomije po kombinacijama

Čak i ako uspijete pokriti sve vjerojatne i nevjerojatne koincidencije na strogo tehničkoj strani, kako softvera tako i hardvera na kojem se izvršava, posao nije gotov: povrh svih tih slojeva sigurnosti, dolazi još i hvatanje u koštac s neizbježnim rizikom koji sa sobom donose sami korisnici. Riječ je o finesama dizajna i korištenja softvera koji se brinu za to da praktički eliminiraju mogućnost da se neka bitna operacija izvede nespretnom koincidencijom.

Tipična praksa je pokrenuti takve osjetljive stvari određenom tipkovničkom kombinacijom koja nije slična niti jednoj drugoj u tom sustavu, te koja koristi tipke koje su uvijek poprilično razmaknute na tipkovnici. Primjerice, lijevi Ctrl, desni Shift i F7, s uvjetom da niti jedna druga tipka pritom ne smije biti pritisnuta. Time se eliminira mogućnost katastrofe, jer se nekome na tipkovnicu prevrnula šalica, ili je na nju skočila mačka.

Osim nespretnosti, treba se “braniti” i od brzopletosti: ovdje je dobar trik svaki put koristiti malo drukčiju tipkovničku kombinaciju, ili, pak, od korisnika tražiti da odgovori na neko pitanje za koje ipak treba razmisliti duže od jedne sekunde. (Taj potonji trik često se vidi kada neki uređaj treba resetirati na tvorničke postavke.)

Razlog zašto takve softverske osigurače ne viđamo u svakodnevnom korištenju softvera jest to što nas većina i ne koristi takve ekspertne sustave koji mogu izazvati ogromne štete. Otkad više nije moguće naprasno izvesti legendarni “format C:”, najveća šteta koju uobičajeni korisnici mogu napraviti jest izgubiti nekoliko sati rada ili određene podatke za koje nema sigurnosnih kopija, pa bi takvi komplicirani sustavi sigurnosti dugoročno korisnicima više smetali nego pomogli. Zbog pogrešne tipke u našim svakodnevnim softverima nitko neće izgubiti život, niti cjeloživotni imetak, niti će se negdje formirati natkritična masa urana-235.

Mobilne tehnologije olakšale su nam sve i svašta – ali i otežale pouzdanost. Primjerice, one vrlo lako mogu ostati bez signala usred bankovne transakcije, i tu je na softveru da razriješi što se zapravo dogodilo
Mobilne tehnologije olakšale su nam sve i svašta – ali i otežale pouzdanost. Primjerice, one vrlo lako mogu ostati bez signala usred bankovne transakcije, i tu je na softveru da razriješi što se zapravo dogodilo
Bug 341 travanj 2021.