0xC000021A: csrss kék halál a laborban

A legutolsó Operációs rendszerek előadáson került elő a hibakeresés témaköre, és ott mutattam egy példát egy nem annyira triviális kék halál (azaz Blue Screen of Death – BSOD, becsületesen nevén STOP hiba vagy bugcheck) megoldására.

Valamikor talán márciusban történt, hogy az egyik laborunkban, ahol 13 teljesen egyforma laptop van, egyszer csak szóltak a többiek, hogy két gép rejtélyes módon folyamatosan újraindult miután megjelent a bejelentkezési képernyő rajtuk. Néha még el lehetett kezdeni rajta a felhasználónevet és jelszót begépelni, de a bejelentkezés végéig már általában nem jutottak el a gépek. A gépeknek elvileg a teljes hardver és szoftver konfigurációja megegyezett, nem volt különösebb változtatás az utóbbi időkben rajtuk, így elég furcsa volt, hogy csak kettőn jelentkezik ez a gond. Végül vagy egy napom ráment, de meglett a hiba oka. A következők mentén haladtam.

1. Automatikus újraindítás kikapcsolása (System properties / Advanced / Startup and Recovery): így akkor megáll a kék képernyőnél, és le lehet olvasni a hibakódot.

image

2. STOP kód azonosítása: Ez volt a pontos STOP kód:

C000021A, {e2a5ee98, c0000005, 7c9106c3, 69ec24}

Az MSDN dokumentációjában meg lehet nézni (Bug Checks): 0xC000021A: STATUS_SYSTEM_PROCESS_TERMINATED

Tehát leáll valamelyik kritikus rendszer folyamat, ami nélkül az operációs rendszer nem tud tovább működni. Ki kéne deríteni, melyik volt az! Úgy volt beállítva a gép, hogy minden egyes BSOD esetén készítsen minidumpot, így azt kellett megszerezni. Ha Csökkentett módban indítottam el a gépet, akkor nem jött elő a hiba, akkor be lehetett jelentkezni. Így a Csökkentett mód hálózattal opciót választottam, és átraktam egy másik gépre a minidump fájlt.

3. Minidump megnézése: a minidump betöltése után a !analyze –v ezt a kimenetet adta WinDbg alatt:

image Tehát a csrss.exe (a windowsos környezeti alrendszer, aminek a feladata többek között a Windows API hívások lefordítása a kernel belső API-jára) halt meg. Azonban a verem tartalmában pont a lényegi részt nem tudjuk beazonosítani, azaz, hogy mi okozta a hibát, hisz ez egy kernel minidump, a felhasználói módú hívásokról nem tárol információt. Ezért egy teljes memória dumpot kellett készíteni.

4. Teljes memória dump készítése: ehhez szimplán a Startup and Recovery résznél a Complete memory dump opciót ki kell választani, azonban az adott gépen nem volt ilyen. Hát ez meg hogyan lehet?? Némi keresgélés után ráleltem erre a KB cikkre: KB274598  Complete memory dumps are not available on computers that have 2 or more gigabytes of RAM (ez a KB cikk jelenleg már valamiért nem érhető el:( ). Tehát Windows XP-n bizonyos esetekben nem lehet teljes dumpot csinálni, ha 2 GB-nál több memóriánk van. A gépekben 4 GB volt:( A megoldás az lett, hogy a boot.ini-ben a /MaxMem=2000 kapcsolóval korlátoztam, hogy mennyi memóriát lásson az operációs rendszer, és így már ki lehetett választani a teljes dumpot is.

5. A teljes dump elemzése: A teljes dump megnyitásakor az !analyze talált egy kivételt is:

EXCEPTION_RECORD:  0069ec08 -- (.exr 0x69ec08)
ExceptionAddress: 7c9106c3 (ntdll!RtlAllocateHeap+0x000001da)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000001
   Parameter[1]: 75e9193e
Attempt to write to address 75e9193e

Tehát az RtlAllocateHeap hívás okozott egy nem kezelt kivételt. Lássuk, ki hívta meg ezt a függvényt:

image Az sxs.dll volt valószínűleg a bűnös, annak az XML névtér kezelő részéből jött valahogy a hibás paraméter. Most tehát az a kérdés, ki az az sxs?

6. SxS – Side by Side assemblies: az SxS feladata, hogy a közös DLL-ekből egymás mellett létezhessenek különböző verziók, és alkalmazások egy Manifest fájlban megadhassák, hogy nekik pontosan melyik verzió kell (About Isolated Applications and Side-by-side Assemblies). Hogy kerülhet ez ide? A következő nyomot itt találtam meg: Activation Context Creation flow, az SxS használatához kell egy activation context, ami így jön létre:

  • CreateProcess/CreateActCtx is called.
  • CreateProcess/CreateActCtx sends the message to CSRSS
  • CSRSS receives the message, creates the activation context
  • Once the activation context is created, CSRSS returns
  • CreateProcess/CreateActCtx proceeds.
  • The getaway from the flow above is: most work is done in CSRSS.exe.

Tehát az sxs tényleg a csrss-t hívja, és ha hiba van, akkor az abban a folyamatban jön elő.

7. A hiba oka: most, hogy tudjuk, hogy hol kell keresni, meg is lehetett találni a hiba okát: The computer may restart when you add a manifest that has the Windows Vista extension to an .exe file or to a .dll file in Windows XP Service Pack 2 (SP2) (KB 921337). Az sxs.dll verzióját ellenőriztem, és tényleg még a régi volt fent: 5.1.2600.2180.

8. A hiba megoldása: próbáltam megtalálni, hogy melyik lehet a problémás manifest fájl, de nem sikerült. Úgyhogy végül a fenti KB cikkben lévő linken igényeltem a megadott javítást, azt elküldték automatikusan, és ezt fel lehetett rakni csökkentett módban is. Újraindítás után nem jelentkezett a gond, így sikerült a problémát megoldani.

A hiba kialakulásának oka: utólag visszanézve valószínűleg az lehetett a gond, hogy ezeket a gépeket nagyon ritkán használtuk ebben a félévben, így nem települt rájuk minden, a WSUS-ban elfogadott frissítés. Az új .NET Framework és a kiegészítései hamarabb mentek fel, mint az XP SP3, ami a fenti javítást tartalmazta, az új komponensek valószínűleg már az újfajta manifest formátumot használták, amit az SP2-es sxs még nem szeretett.

Advertisements
Kategória: Opre
Címke:
Közvetlen link a könyvjelzőhöz.

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s