Binary Compatibility #1 - Áttekintés

Tisztában vagyok vele, hogy ennél ellentmondásosabb témáról nemigen lehetne írni erre az oldalra, plusz ez az a kérdés az amiről általában óriási káosz uralkodik a fejekben, és legtöbben azt sem tudják, eszik-e azt, vagy isszák, de mégis nagy mellénnyel nyilatkoznak róla hozzászólásaikban - általában igazodva az általuk mérvadónak tekintett hozzább-értők véleményéhez. Pedig fontos, hogy mindenki akit kicsit is érdekelnek a szakmai dolgok tisztában legyen azzal, hogy miről is van szó, mert a kérdés és az azzal kapcsolatos problémák az informatika minden területén jelen vannak. Persze körüljárni az egészet minden bizonnyal ismét egy post-sorozatba fog torkollni, de azért csak kezdjünk bele, a végére csak kilyukadunk valahol.

A szép kis fenti prológus után még annyit bocsátanék előre, hogy a leirtak a személyes véleményemet képezik, amelyet húsz év programozási tapasztalat, tizen-egynéhány operációs rendszer és vagy féltucat processzorarchitektúra megismerése alapján alakítottam ki - ennek ellenére nem kizárt, hogy tévedek, tehát nyugodtan tessék egyet nem érteni, és persze minden egyes megállapításom után odaképzelni, hogy "szerintem".

És akkor most in medias res - a bináris kompatibilitás márpedig jó dolog. Néhány nagyon egyszerű példával illusztrálhatjuk hogy miért: kapásból itt van a processzorok utasításkészlete. A hardveripar legnagyobb és legismertebb cégei évente sokmillió dollárt fordítanak arra, hogy a következő generációs processzorok a belső fejlesztéseik ellenére képesek legyenek futtatni az elődeik - sokszor egészen távoli elődeik - számára készített programokat is. Igen, az hogy a legújabb Core2 Quad futtatni képes egy 8086 számára készített programot is, a bináris kompabilitás ékes példája. Másik példa: az internet - és mellékesen az összes számítógép hálózat. A számítógép hálózatok működését jól definiált bináris protokollok biztosítják. Nem is lehet másként, hiszen ezek hardverközeli dolgok, a hardver pedig csak a bináris, és általában a számokkal leírt dolgokat érti meg. Aztán a következő jó példa a fájlformátumok. Képzeljük el mi lenne, ha egy zlib, vagy másféle tömörítő új változata nem lenne kompatibilis az előző verziójával betömörített állományokkal... Biztosan nem sokan használnák a továbbiakban. Hasonló a helyzet a különféle kép-, video- és zeneformátumokkal, a DVD lemezek, vagy akár a fájlrendszerek formátumaival is. Ezek mind-mind egy-egy bináris kompatibilitási réteget képeznek. Összefoglalva, egy bináris kompatibilitási réteg nem tesz mást mint hardverközeli módon meghatározza, hogy az adatok milyen formában kerülnek tárolásra, vagy átadásra a rendszerek, vagy a rendszerek részei között. Szerintem túlzás nélkül kijelenthetjük - bináris kompatibilitási rétegek nélkül számítástechnika szimplán működésképtelen lenne. Akkora káosz uralkodna, hogy nagyobb rendszereket képtelenség lenne üzemeltetni és ezeket a rendszereket rémálom lenne egymáshoz kapcsolni. A bináris kompatibilitási rétegek olyan támpontokat adnak amire a fejlesztők - és rajtuk keresztül a felhasználók is támaszkodhatnak. Viszonylagos rendet biztosítanak, egy természeténél fogva bonyolult, ezáltal némiképp kaotikus rendszerben.

Természetesen, minden bináris kompatibilitási rétegnek megvan az árnyoldala is: mint minden fixen rögzített pont, nem csak biztonságot ad, mint egy korlát, hogy ne zúgj le a lépcsőn, vagy lépj le a busz elé az iskola (vagy a kocsma) előtt - hanem gátolhat is céljaid elérésében. Adott esetben tehát kerülgetni kell - a rosszul definiált vagy teljesen elavult bináris interfészek jelentős problémát, késéseket és pluszmunkát okozhatnak egy egy új fejlesztés során. Tipikus példája ennek az x86 utasításkészlet amivel az eszmefuttatásunkat kezdtük - kevés korlátoltabb és elavultabb bináris interfészt támogat a globális iparág napjainkban, mégis szükség van rá, mert nélküle a már megírt és széles körben használt szoftverek nagyrészét lehúzhatnánk a vécén. A fentiek alapján könnyű belátni, hogy a bináris interfészek a kód újrafelhasználhatóság terén sokkal jelentősebb tényezőnek számítanak, mint például az OOP nyelvi elemek, amelyet olyannyira szeretnek hangoztatni a témában látszólag járatosak.

Ha már a nyelvi elemeknél tartunk, van mégegy terület, ahol jelentős szerepet kap a bináris kompatibilitás, ez pedig a fordítóprogramok. A magas szinten dolgozó programozók hajlamosak elfeledkezni, mi is történik akkor, mikor lefordítják a programjukat, pedig ha megértenék és a munkájuk egyik szempontjaként fejben tartanák az ekkor zajló folyamatokat, biztosan jobb szoftverek születnének. A fordítóprogramok munkájában két elem kap kulcsszerepet, az egyik az API, a másik az ABI. Az API-t vagyis az Application Programming Interface-t természetesen a programozók használják, a forráskód szintjén, és egy átlagos program jobbára API hivások tömkelegéből áll. A legtöbb széles körben felhasznált felhasznált API-nál törekednek az állandóságra és visszafele kompatibilitásra, illetve fordítva: egy API általában azért terjed el, mert jól megtervezett, állandó és visszafele kompatibilis. Az ABI szerepe nem ilyen látványos, pedig legalább ilyen fontos: az Application Binary Interface, amely a mélyben dolgozik, és azt definiálja a processzor nyelvén, hogy a már lefordított programrészek, függvények, milyen módon hívhatják egymást, melyik paraméterek melyik regiszterben kerülnek átadásra, vagy milyen formában kerülnek például a stackbe. A régebbi architektúrákon, mint amilyen az x86 is, kezdetben nem volt szigorúan definiált ABI. Az assembly programok korában mindenki úgy használta a regisztereket ahogy jól esett, egy központi szabvány hiányában pedig a fordítóprogramok és az operációs rendszerek saját ABI-kat definiáltak maguknak. Vagyis az ABI sokszor változott, és általában minden operációs rendszernek saját ABI-ja van, esetleg egy rendszer többet is használhat a régebbiek közül, attól függően, hogy az adott alrendszert milyen régen tervezték. Más fiatalabb processzorarchitektúrákon azonban ennél jobb a helyzet, hiszen az első fordítóprogramokkal általános célú ABI-t is terveztek és publikáltak, amelyet azóta is használnak a rendszerek és a rá írt fordítóprogramok, és az ezekkel a rendszerekkel dolgozó programozók élvezik az állandó, egységes és kiszámítható szoftverkörnyezet előnyeit. Mindenesetre, valamilyen jól definiált ABI nélkül lehetetlen, vagy rettentő körülményes lenne a moduláris programozás, és nemcsak a dinamikus, de még a statikus függvénykönyvtárak használata is. Legyen bármilyen kaotikus is az éppen fordított kód és a felhasznált API, odalent a lefordított kód mélyén, az ABI szintjén a fordító szép egységes definiált sémákat, binárisan kompatibilis hivásokat fordít belőle.

Összegezzük tehát:
* a bináris kompatibilitás amellett, hogy szükséges, jó is, mert a jól megtervezett bináris interfészek támpontot adnak, és a korábbi bináris modulok újrafelhasználhatósága miatt - bár adott esetben extra munkát jelentenek a kód írásakor - nagyságrenddel több munkát spórolhatnak meg.
* valamennyi hardverarchitektúra és fordítóprogram figyel a bináris kompatibilitásra, hiszen enélkül a rendszerek működésképtelenek lennének
* összességében aki ezekután szándékosan a bináris kompatibilitás ellen dolgozik az szimplán egy retardált hülye, aki tudatlanságból vagy rosszindulatból szopat másokat.

Postsorozatunk következő részeiben megnézzük, hogy is működik a processzor szintjén egy bináris interfész, az egyes operációs rendszerek hogyan viszonyulnak a bináris kompatiblitás kérdéséhez és problémájához, valamint tervezünk egy bináris interfészt is, hogy személtessük milyen szempontokat is kell figyelembe venni egy ilyen interfész tervezésekor, valamint mekkora feladatot jelent egy ilyen interfész karbantartása. Megmutatjuk, hogy sajnos milyen tipikus hibákat szokás elkövetni egy bináris interfész tervezésekor, valamint ez hogyan vezet ahhoz, hogy a bináris interfész karbantartása nehézkes lesz, kompatibilitása pedig rövid időn belül megszűnik és talán érinteni fogjuk azt a roppant érzékeny kérdést is, hogy ezekben az esetekben mennyi minden múlik a programozó hozzáállásán és szakértelmén.

(És ha valakinek van még ötlete, milyen kérdést érintsünk még, miközben körbejárjuk a témát, ne tartsa magában.)

Hozzászólások

>> bináris kompatibilitási réteg nem tesz mást mint hardverközeli módon meghatározza, hogy az adatok milyen formában kerülnek tárolásra, vagy átadásra a rendszerek, vagy a rendszerek részei között

szerintem nem feltétlenül hardverközeli módon történik ez

Igen és nem. Ha valamit binárisan fogalmazol meg, az mindig hardverközelibb lesz szerintem, mint egy XML fájl vagy forráskód. Ez nem jelenti persze azt, hogy tervezésekor egy bizonyos hardvert vettek figyelembe, de mindig ottvannak a hardver kérdések is (kapásból az endianness és a mindenféle alignmentek jutnak eszembe). Sokszor ezek persze csak az interfész "teljesítményét" befolyásolják, a funkcionalitását nem.

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

A Java bytecode-hoz keszult processzor is anno... :) De a VM amugyis egy virtualis processzor akar lenni. Szoval szerintem rafoghato, hogy hardverkozeli, de ertem mire gondolsz. Mondjuk akkor inkabb ugy, hogy alacsony szintu. :) Nyilvan nincs fekete es feher, osszemosodnak itt is a teruletek, mint mindenhol az eletben.

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Termeszetesen sok helyen jo a binaris kompatibilitas. Azonban erdemes elgondolkodni azon, ha annakidejen nem a binaris, leforditott program szintjere tettek volna a kompatibilitasi kovetelmenyt, hanem forraskod szintre: sok buktatoja van, de ha letezik az adott fordito az ujabb architekturara, akkor nyugodtan ki lehet dobni a regit - a forraskod ismereteben. Persze kompatibilitasi reteg akkor is kellett volna: API szinten mondjuk.
Ha a FOSS korabban megerosodik, akkor most nem a toldozott-foldozott x86 lenne a vezeto architektura, hanem valami korszeru. A programokat le lehetne forditani ra telepiteskor, mint pl. gentoo eseten. A kompatibilitas megmaradna, csak forraskod szinten. Termeszetesen valami esszeru fileformatum kellene hozza, es a programozokat is ra kellene nevelni arra, hogy ugy programozzanak, mas architekturan is futtathato legyen a program. A HW fejlesztesen lenne a hangsuly, es nem a SW fejlesztoke lenne a fo szerep (a fejlesztesert kapnanak penzt, nem eladott darabszamert). Ha a SW fejleszto nem hajlando mellekelni a forrast, elobb-utobb kihal az adott HW-rel egyutt.
Sok helyen santit, van, ahol a binaris kompatibilitas elkerulhetetlen, de az alapelv azt hiszem mukodott volna: bizonyitek ra a sok hordozhato program, es a forrasalapu disztribuciok.

----
Sooner or later you had to talk, even if it was only because you'd run out of things to throw. - Pratchett
honlap készítés

Termeszetesen valami esszeru fileformatum kellene hozza, es a programozokat is ra kellene nevelni arra, hogy ugy programozzanak, mas architekturan is futtathato legyen a program

Ez, ma mar a Java/C#/Python/Perl koraban (sajnos es hibas nezpont) nem divat. Sot, konkretan lenevelik rola az embert.

---
pontscho / fresh!mindworkz

A forrasszintu kompatibilitas olyan hatulgombolosoknak valo potcselekves, akik nem birjak ertelmezni a binaris kompatibilitast, mert nem ertenek olyan szinten a hardverhez. :)

Komolyra forditva, kezdjuk ott, hogy a binaris kod is csak kod, csak eppen a processzor szamara ertelmezheto. Kello szakertelemmel ugyanolyan atlathato, mint barmelyik forraskod - bizonyitjak ezt a megannyi sechole kihasznalasara epult crackek, meg a warez-hegyek.

Egyebkent egy kesobbi postban gondoltam erinteni, hogy miert nem megoldas a forraszintu kompatibilitas: egyreszt iszonyu eroforrasigenyes mindent hasznalat elott leforditani, es ma is vannak jocskan kisteljesitmenyu hardverek, mikozben a fejlesztoeszkozok egyre bonyolultabbak es lassabbak. Masreszt pedig ezzel rohadtul nem kerulted meg a problemat, a lefordult alkalmazasoknak eppugy binaris szinten kell tudnia kommunikalni egymassal.

Masreszt meg en programozo vagyok, ebbol elek. Es napi 8 ora programozas utan otthon valahogy baromira nincs kedvem orakat arra varni, hogy a GCC4 kiszenvedje magabol az amugy - normalis forditokhoz merten - atomfos kodot. Es en legalabb meg tudnam csinalni - csak nem akarom. Az atlag user meg se tudja csinalni az ilyesmit, ha akarja se.

Es meg van sok mas erv is az ellen amit mondasz, mert tobbek kozott arra epit, hogy "mi lett volna ha" marpedig ilyen nincs a fociban, ahogy mondani szoktak. Egyszoval mindez a mai viszonyok kozott abszolut irrealis. Es minel tovabb eroltetik, annal tovabb ragad meg 1% kornyeken a Linux a desktopon. Ugyanis az effele ertelmetlenul kotjuk az ebet a karohoz FOSS mentalitasnak jelentos szerepe van abban, hogy nemcsak a felhasznalok nem fordulnak a Linux fele, de rettento sok szakmabeli is elfordul, akinek egykor koze volt hozza. Nekem itthon majd minden gepemen van Linux, megis kerulom, ha tehetem. Es nem vagyok ezzel egyedul (hi Pontscho!).

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Mert kell. Munkaeszköz. És pont ez a problémám. Olyan érzésem van az utóbbi időben, mintha bármilyen probléma Linuxszal történő megoldása előtt össze kell raknom magát a szerszámot is. És távolról sem lesz tökéletes arra amire használni akarnám. Már jó 10 éve használok valamilyen formában Linuxot és még emlékszem: nem volt ez mindig így. És tulajdonképpen pont ez a probléma, erről szól az egész... A barátnőm pedig magától kéri a Linuxot a gépére, nem én traktálom vele.

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Hat mit mondjak, mas oprendszerekkel se jobb a helyzet, maximum nem ugyanazok a szopasok vannak. Nekem windowssal konkretan az az erzesem, hogy onalloan gondolkodik, es szivesseget tesz nekem azzal, hogy azt csinalja, amire eppen utasitom. Ez Linux eseteben sose fordul elo velem, az csak teszi a dolgat. Oke, hogy egyszer ossze kell pakolni, de ha kello szakertelemmel allok neki, es jol valasztom meg az eszkozt, akkor nem lesznek problemaim. Ha nem... nos akkor csak magamat okolhatom. Persze mindenkinek mas ezzel kapcsolatban a velemenye, es en nem is fogok senkit valtoztatasra kapacitalni. Csak arra osztonozni, hogy elgondolkodjon, hogy biztos, hogy a celnak megfelelo eszkozt valasztotta, vagy csak ugy valasztott egy eszkozt, remelve, hogy passzol a celhoz.

Mert kell. Munkaeszköz.

Milyen munka az, amit csak Linux-al tudsz megoldani?

Olyan érzésem van az utóbbi időben, mintha bármilyen probléma Linuxszal történő megoldása előtt össze kell raknom magát a szerszámot is.

Ha egy eszközzel ennyi szopás van, akkor lehet el kéne gondolkodni azon, hogyan helyettesítheted mással. Korábbi postjaidból az derült ki, hogy van OSX-ed, dolgozol Windows-al, fejlesztessz Java-ban, van egy csomó !Intel géped, szóval ilyen széles látókörrel nem hiszem, hogy ez probléma lenne. Bátran ott kell hagyni a Linux-ot és meg kell próbálkozni pl. *BSD-vel, Solaris-al.

init();

Bátran ott kell hagyni a Linux-ot és meg kell próbálkozni pl. *BSD-vel, Solaris-al.

Ezekbol 0db fut barmelyik gepemen. A NetBSD-t emberemlekezet ota igerik Pegasosra, azota sincs, Solaris detto, iBookon meg OSX van, de azon amugysem tul celszeru szerver feladatokat beuzemelni. Ezenkivul van legalabb 10-12db Linux, amit valaha beuzemeltem, szerteszet a vilagban, ezeket karbantartani kell, es a legtobb nem olyan, hogy elfingom magam, es lecserelik egybol masra. Sz'al illendo valami tesztkornyezet mielott belepiszkalok, meg karbantartani az ismeretem a recent disztrokkal kapcsolatban, es maris a jelen helyzetet kapjuk. Arrol nem is beszelve, hogy a Linuxos munkak neha manapsag is megtalalnak (lasd a legutobbi szopasaim, hozott anyag, nem en dontom el, hogy mivel kell megoldani). . Az X, a Gnome meg ezek meg ugyanakkora bloatware fosok barmelyik platformon, szoval... Tok konnyu a "hasznalj mast" meg a "javitsd ki" c. hulyeseget szajkozni. Ha a Linux nem lenne tenyezo, le sem szarnam. De az. Es sajnos egyre ritkabban pozitiv tenyezo a kepletben.

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Tok konnyu a "hasznalj mast" meg a "javitsd ki" c. hulyeseget szajkozni.

Oké, nem szajkózom, de ha hosszú ideje szopnék Linux-al, mégiscsak elgondolkodnék a továbblépésen. Én is használok Linux-ot, gyak. csak szerveren, mert az utóbbi 8 hónapban a havi egy-két Kubuntu bootolást desktopon nem mondanám rendszeres használatnak. :) Szerveren ennyi problémát sosem tapasztaltam, lehet szerencsém volt.

Ha a Linux nem lenne tenyezo, le sem szarnam. De az. Es sajnos egyre ritkabban pozitiv tenyezo a kepletben.

Ez utóbbi tényleg baj.

init();

"A kompatibilitas megmaradna, csak forraskod szinten."

Jaj, ez az újrafordítósdi... Azoknak jó ez a "hát nem megy, újrafordítom", akik nem képesek megoldani a bináris komatbilitás kérdését.

Csak ez esetben ne is álmodjak arról, hogy mondjuk egy binárist akarok átvinni a rendszerről b rendszerre, továbbá arra se lehet alapozni, hogy X rendszeren fut Y verziójú libbel a Z rendszeren Y-1 verziójú libbel fordított program, mert ki tudja, hogy mit variáltak az API-ban vagy nem változott-e meg a fordítóprogram, ami miatt másképp fordít, stb.

anno, egyik ügyfél 32bites s/390-én futott egy `65-ből származó 8 bites program.
az már az idők homályába vész, h mi szükség van egy ~40 éves programra: nem volt meg a forrása, h alakítsanak rajta, vagy nem volt erőforrás, h átírják (COBOL programozókat most is keresnek, csak nem találnak), vagy csak egyszerűen a mai napig megfelel arra amire használják.

fut ez is, csak szól, h máshol lett fordítva (hiába ez már nem mainframe):
$ lsof
lsof: WARNING: compiled for AIX version 5.1.0.0; this is 5.2.0.0.