Megosztás:


Felügyelt végrehajtási folyamat

A felügyelt végrehajtási folyamat a következő lépéseket tartalmazza, amelyeket a témakör későbbi részében részletesen ismertetünk:

  1. Fordító kiválasztása. A közös nyelvi futtatókörnyezet által biztosított előnyök eléréséhez egy vagy több olyan nyelvi fordítót kell használnia, amely a futtatókörnyezetet célozza.
  2. A kód fordítása köztes nyelvre. A fordítás lefordítja a forráskódot egy közös köztes nyelvre (CIL), és létrehozza a szükséges metaadatokat.
  3. A CIL fordítása natív kódra. A végrehajtási időben egy igény szerinti (JIT) fordító natív kódra fordítja le a CIL-t. A fordítás során a kódnak át kell adnia egy ellenőrzési folyamatot, amely megvizsgálja a CIL-t és a metaadatokat annak megállapításához, hogy a kód biztonságos-e.
  4. A kód futtatása. A közös nyelvi futtatókörnyezet biztosítja azt az infrastruktúrát, amely lehetővé teszi a végrehajtást és a végrehajtás során használható szolgáltatásokat.

Fordító kiválasztása

A közös nyelvi futtatókörnyezet (CLR) által biztosított előnyök eléréséhez egy vagy több olyan nyelvfordítót kell használnia, amely a futtatókörnyezetet célozza, például Visual Basic, C#, Visual C++, F#, vagy a számos külső fordító, például az Eiffel, a Perl vagy a COBOL fordító egyikét.

Mivel ez egy többnyelvű végrehajtási környezet, a futtatókörnyezet számos adattípust és nyelvi funkciót támogat. A használt nyelvfordító határozza meg, hogy mely futtatókörnyezeti funkciók érhetők el, és ezeket a funkciókat használva tervezheti meg a kódot. A fordító, nem a futtatókörnyezet, határozza meg a szintaxist, amelyet a kódnak használnia kell. Ha az összetevőnek teljesen használhatónak kell lennie más nyelveken írt összetevőkkel, az összetevő exportált típusainak csak a Common Language Specification (CLS) által tartalmazott nyelvi funkciókat kell elérhetővé tenni. Az attribútummal CLSCompliantAttribute meggyőződhet arról, hogy a kód CLS-kompatibilis. További információ: A nyelv függetlensége és a nyelvfüggetlen összetevők.

Fordítás a CIL-be

A felügyelt kód összeállításakor a fordító lefordítja a forráskódot egy közös köztes nyelvre (CIL), amely egy processzorfüggetlen utasításkészlet, amely hatékonyan konvertálható natív kódmá. A CIL utasításokat tartalmaz az objektumok betöltési, tárolási, inicializálási és hívási módszereire, valamint az aritmetikai és logikai műveletekre, a vezérlési folyamatokra, a közvetlen memória-hozzáférésre, a kivételkezelésre és más műveletekre vonatkozó utasításokat. A kód futtatása előtt a CIL-t cpu-specifikus kódmá kell konvertálni, általában egy igény szerinti (JIT) fordítóval. Mivel a közös nyelvi futtatókörnyezet egy vagy több JIT-fordítót biztosít minden támogatott számítógéparchitektúrához, ugyanez a CIL-készlet jiT-fordítással és bármilyen támogatott architektúrán futtatható.

Amikor egy fordító létrehozza a CIL-t, metaadatokat is létrehoz. A metaadatok a kód típusait ismertetik, beleértve az egyes típusok definícióját, az egyes típusok tagjainak aláírását, a kód által hivatkozott tagokat és az egyéb adatokat, amelyeket a futtatókörnyezet a végrehajtáskor használ. A CIL és a metaadatok egy hordozható végrehajtható (PE) fájlban találhatók, amely a Microsoft által publikált végrehajtható tartalomhoz használt PE és általános objektumfájl-formátum (COFF) alapjaira épül és azt bővíti. Ez a fájlformátum, amely CIL-t vagy natív kódot, valamint metaadatokat tartalmaz, lehetővé teszi az operációs rendszer számára a gyakori nyelvi futtatókörnyezeti rendszerképek felismerését. A metaadatok jelenléte a fájlban a CIL-vel együtt lehetővé teszi a kód leírását, ami azt jelenti, hogy nincs szükség típuskódtárakra vagy interfészdefiníciós nyelvre (IDL). A futtatókörnyezet szükség szerint megkeresi és kinyeri a metaadatokat a fájlból a végrehajtás során.

CIL fordítása natív kódra

A közös köztes nyelv (CIL) futtatása előtt azt a közös nyelvi futtatókörnyezet alapján kell lefordítani a célgép architektúrájának natív kódjához. A .NET kétféleképpen hajtja végre az átalakítást:

JIT fordítóval történő fordítás

A JIT-fordítás igény szerint natív kódmá alakítja a CIL-t az alkalmazás futtatókörnyezetében, amikor a rendszer betölti és végrehajtja a szerelvény tartalmát. Mivel a közös nyelvi futtatókörnyezet jiT-fordítót biztosít minden támogatott CPU-architektúra számára, a fejlesztők létrehozhatnak egy CIL-szerelvényeket, amelyek JIT-fordítással és különböző gépi architektúrákkal futtathatók különböző számítógépeken. Ha azonban a felügyelt kód platformspecifikus natív API-kat vagy platformspecifikus osztálytárakat hív meg, az csak ezen az operációs rendszeren fog futni.

A JIT-fordítás figyelembe veszi annak lehetőségét, hogy bizonyos kódokat lehet, hogy sosem hívnak meg a végrehajtás során. Ahelyett, hogy időt és memóriát használ a PE-fájlban lévő összes CIL natív kódká alakításához, a CIL-t szükség szerint konvertálja a végrehajtás során, és a kapott natív kódot a memóriában tárolja, hogy az elérhető legyen a folyamat kontextusában a későbbi hívásokhoz. A betöltő egy csonkot hoz létre és csatol egy típus minden metódusához, amikor a típus betöltődik és inicializálódik. Amikor első alkalommal hív meg egy metódust, a csonk átadja a vezérlést a JIT-fordítónak, amely a metódus CIL-ját natív kódmá alakítja, és módosítja a csonkot, hogy közvetlenül a létrehozott natív kódra mutasson. Ezért a JIT által lefordított metódus későbbi hívásai közvetlenül a natív kódra kerülnek.

Telepítés idején végzett kódlétrehozás a NGen.exe használatával

Mivel a JIT-fordító natív kódmá alakítja a szerelvény CIL-jét az adott szerelvényben definiált egyes metódusok meghívásakor, a futásidőben hátrányosan befolyásolja a teljesítményt. A legtöbb esetben ez a csökkent teljesítmény elfogadható. Ennél is fontosabb, hogy a JIT-fordító által létrehozott kód a fordítást kiváltó folyamathoz van kötve. Nem osztható meg több folyamat között. Annak érdekében, hogy a generált kód megosztható legyen egy alkalmazás több meghívása vagy több olyan folyamat között, amely több összeállítással rendelkezik, a közös nyelvi futtatókörnyezet támogatja az idő előtti fordítási módot. Ez az idő előtti fordítási mód a Ngen.exe (natív képgenerátor) használatával konvertálja a CIL-szerelvényeket natív kódmá, hasonlóan a JIT-fordítóhoz. A Ngen.exe működése azonban három módon különbözik a JIT-fordító működésétől:

  • A CIL-ről natív kódra való konvertálást hajtja végre, mielőtt az alkalmazást futtatja az alkalmazás futtatása helyett.
  • Egyszerre egy teljes egységet fordít le, ahelyett hogy egyetlen metódust tenne meg egyszerre.
  • A natív képgyorsítótárban létrehozott kódot a lemezen tárolt fájlként megőrzi.

Kódellenőrzés

A natív kódra való fordítás részeként a CIL-kódnak át kell esnie egy ellenőrzési folyamaton, kivéve, ha a rendszergazda olyan biztonsági szabályzatot hozott létre, amely lehetővé teszi a kód megkerülését. Az ellenőrzés megvizsgálja a CIL-t és a metaadatokat annak megállapításához, hogy a kód biztonságos-e, ami azt jelenti, hogy csak azokhoz a memóriahelyekhez fér hozzá, amelyekhez hozzáférése van. A típusbiztonság segít elkülöníteni az objektumokat egymástól, és segít megvédeni őket a véletlen vagy rosszindulatú sérülésekkel szemben. Emellett biztosítja, hogy a kódra vonatkozó biztonsági korlátozások megbízhatóan kikényszeríthetők.

A futtatókörnyezet arra a tényre támaszkodik, hogy a következő állítások igazak a garantáltan típusbiztos kódra:

  • Egy típusra mutató hivatkozás szigorúan kompatibilis a hivatkozott típussal.
  • Egy objektumon csak a megfelelően definiált műveletek lesznek meghívva.
  • Az identitások azok, amelyekről azt állítják, hogy azok.

Az ellenőrzési folyamat során a rendszer megvizsgálja a CIL-kódot annak ellenőrzésére, hogy a kód csak megfelelően meghatározott típusok használatával tud-e hozzáférni a memóriahelyekhez és a hívási módszerekhez. Például a kód nem engedélyezheti az objektum mezőinek elérését olyan módon, amely lehetővé tenné a memóriahelyek felülírását. Emellett az ellenőrzés ellenőrzi a kódot annak megállapításához, hogy a CIL megfelelően lett-e létrehozva, mert a helytelen CIL a típusbiztonsági szabályok megsértéséhez vezethet. Az ellenőrzési folyamat egy jól definiált típusbiztos kódkészletet ad át, és csak a biztonságos típusú kódot adja át. Előfordulhat azonban, hogy néhány típusbiztos kód nem felel meg az ellenőrzésnek az ellenőrzési folyamat bizonyos korlátozásai miatt, és egyes nyelvek a tervezés során nem hoznak létre ellenőrizhetően típusbiztos kódot. Ha a biztonsági szabályzat írja elő a típusbiztos kódot, de a kód nem felel meg az ellenőrzésnek, kivétel történik a kód futtatásakor.

Kód futtatása

A közös nyelvi futtatókörnyezet biztosítja azt az infrastruktúrát, amely lehetővé teszi a felügyelt végrehajtás végrehajtását, valamint a végrehajtás során használható szolgáltatásokat. A metódus futtatása előtt a metódust processzorspecifikus kódra kell lefordítani. Minden metódust, amelyhez CIL jött létre, JIT-tel fordítják, amikor először meghívják, majd lefut. A metódus következő futtatásakor a rendszer futtatja a meglévő JIT által lefordított natív kódot. A JIT-fordítás, majd a kód futtatásának folyamata a végrehajtás befejezéséig ismétlődik.

A végrehajtás során a felügyelt kód olyan szolgáltatásokat kap, mint a szemétgyűjtés, a biztonság, a nem felügyelt kódokkal való együttműködés, a nyelvek közötti hibakeresési támogatás, valamint a fokozott üzembe helyezés és verziószámozás támogatása.

A Microsoft Windows Vista rendszerben az operációs rendszer betöltője a COFF fejléc egy részének vizsgálatával ellenőrzi a felügyelt modulokat. A beállított bit egy felügyelt modult jelöl. Ha a betöltő észleli a felügyelt modulokat, betölti mscoree.dll, és _CorValidateImage és _CorImageUnloading értesítik a betöltőt, amikor a felügyelt modulok képei betöltődnek vagy eltávolítódnak. _CorValidateImage a következő műveleteket hajtja végre:

  1. Biztosítja, hogy a kód érvényes felügyelt kód legyen.
  2. A kép belépési pontját módosítja a futtatókörnyezet belépési pontjára.

64 bites Windows rendszeren a _CorValidateImage a memóriában lévő rendszerképet PE32-ről PE32+ formátumra alakítva módosítja.

Lásd még