Bluescreen
Bluescreen
Author
Markus Lassfolk
Rapid Response Engineer
Security Lead & Windows Platforms Team
Microsoft Product Support Services
Disclaimer
Content rebublished with permission from author
The content is in Swedish, deal with it.
Alla har vi tyvärr råkat ut för en och annan “Blåskärm” eller också kallad BSOD, Bluescreen of Death.
De flesta som jobbar med IT har ingen aning om vad en bluescreen innehåller, vad man kan göra med den, eller kanske inte heller varför den uppstår så jag ska försöka ge en väldigt kort pressentation och guide för hur ni kan gå vidare med en bluescreen.
Det tekniskt korrekta namnet för Bluescreen är “Bug check” men kallas också ibland system crash, kernel error eller Stop error. När Windows inte kan garantera att systemer är stabilt så skapas en sådan här. Det kan t.ex vara att ett närverkskort har ett fel som gör att den skriver en etta istället för en nolla, en s.k bitflip eller att en drivrutin läser/skriver från ett felaktikt minnesområde.
Det är förutom en varning att någonting gick fel ett sorts skydd mot bl.a dataförlust hur konstigt det än må låta. T.ex om en server på en bank skulle skriva en nolla istället för en etta någonstans så skulle det i slutändan kunna resultera i enormt stora fel eller i någon workstation som beräknar hållfastheten på en bro. Så fort Windows då känner av att någonting blev fel så blåskärmar den alltså för att inte felet skall bli större och orsaka fler fel.
Windows kan beroende på version (NT3.5, NT4, 2000, XP, 2003) vara inställt på lite olika sätt för hur det skall agera vid en blåskärm. T.ex om den skall skriva en Full Memory Dump, Kernel Dump eller Mini-Dump.
- Complete Memory Dump innehåller all information som fanns i RAM när felet hände.
- Kernel Memory Dump innehåller det minnet Kerneln (och HAL) använde just då.
- Small Dump är en 64k fil med bara den senaste informationen.
Då en bluescreen sker i Kernel Mode (i application mode skapar DrWatson dumpar) så räcker det oftast med en Kernel Dump som också är mycket mindre än en full dump, ca en tredjedel av minne, men kan variera mycket beroende på omständigheterna.
Personligen föredrar jag att få en Full Dump om möjligt för att ha all information tillgänglig men om man har flera Gb RAM i en server är det inte alltid praktiskt möjligt.
En bluescreen kan innehålla en mängd olika information och den viktigaste informationen (bugkoden mm) sparas också till Eventloggen.
T.ex kan en dump se ut så här
————————————————————————
STOP: 0×00000079 (0×00000002, 0×00000001, 0×00000002, 0×00000000)
Mismatched kernel and hal image.
Beginning dump of physical memory
Physical memory dump complete. Contact your system administrator or
technical support group.
————————————————————————
Eller så här:
————————————————————————
STOP: c000021a {Fatal System Error}
The Windows Logon Process system process terminated unexpectedly with
a status of 0×00000001 (0×00000000 0×00000000).
The system has been shut down.
————————————————————————
Det är helt beroende på felkoden och typen av fel.
Det Hexadecimala numret efter STOP: kallas “Bug check code” eller “Stop Code” och är det absolut viktigast informationen på skärmen. Därefter kommer 4 koder till som kan vara av nytta.
I den första dumpen syns alla 4 medans i den andra ser man 3 stycken i texten, om mindre än fyra syns kan man anta att de är 0×00000000. Dessa koder referrerar bland annat till den minnesaddressen där felet skedde och om det var ett Läs eller Skrivfel.
Resten av Texten kan ge mer information så som vilken driver som eventuellet orsakade det. Jag säger eventuellt då man inte kan lita på den texten. Jag skall förklara varför senare. Det kan också vara en liten beskrivning på varför det skedde och förslag på hur man kan åtgärda felet.
För att skapa en Full Minnesdump finns det ett par saker man måste säkerställa.
1. Gå in i Control Panel -> System -> Advanced -> Startup and Recovery: Settings
2. Kryssa i och välj följande :
x Write an event to the system log
x Complete Memory Dump
x Dump File: %SystemRoot%\MEMORY.DMP eller annan disk där det finns mycket ledig plats
x Overwrite any existing file
3. Clicka OK
4. Ställ in att HELA Pagefilen skall ligga på systemdriven (oftast c:\) och INTE vara splittad på flera andra partitioner!
5. Säkerställ att Pagefilen är större än RAM+50mb (1gb RAM = större än 1074mb pagefile)
6. Rensa så det finns mer ledigt plats där %SystemRoot%\MEMORY.DMP kommer ligga än Pagefile är stor. (Pagefile 1074 = minsta ledigt utrymme 1080mb)
7. Boota om
Det Windows då gör när en bluescreen uppstår är att den Skriver ett event till Event Loggen, Visar Bluescreenen och dumpar ner allt från RAM i Pagefilen. Under nästa uppstart kommer Windows sedan att kopiera pagefile.sys till %SystemRoot%\MEMORY.DMP samt att på vissa Windows Versioner skapas automatiskt en Small MemoryDump i %systemroot%\Minidump
Oftast är %systemroot% = c:\windows eller c:\winnt.
T.ex på en Server med 4gb i RAM kan det vara opraktiskt eller omöjligt att skapa en pagefile på c:\ som är 4gb stor och även ha 4gb ledigt för att spara memorydumpen. Om man inte har plats kan man använda /MAXMEM=1024 i boot.ini för att begränsa Windows till att använda enbart 1gb i RAM och därmed räcker det med 1gb (+50mb) pagefile.
Det kan givetvis inverka på prestandan men det är kanske inte heller alltid man använder all RAM i Servern och då blir det inte så stor performance impakt. Det får man bedömma från fall till fall.
Okej, så nu har vi fått en full memorydump kallad c:\windows\memory.dmp, vad gör man sen då?
Då kan man börja med att surfa in på http://oca.microsoft.com/en/Welcome.asp och där tanka upp memory.dmp som automatiskt analyseras och är det ett känt problem får man även en lösning för problemet.
Eller så laddar man debuggern och sätter igång själv och försöker hitta orsaken. Det första stegen när man kör Debugging är väldigt lätt och ger i många många fall orsaken till dumpen men om det inte gör det så är tröskeln väldigt hög innan man kan få fram orsaken själv. Vi brukar säga att “Debugging is an Art”, det är egentligen ingenting man kan läsa sig till utan krävs massor av övning och färdighet och praktiskt erfarenhet innan man lär sig se mönster och lär sig hur man skall tackla olika sorters dumpar.
Börja med att tanka hem och installera Debugging Tools (Windbg) från http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx
Sedan startar du WinDBG som är det programmet som är lättast att använda och ladda in minnesdumpen i.
För att ge oss mer information från dumpen måste vi ladda så kallade Symbol Files. Då kan man antingen tanka hem och installera diverse olika paket lokalt på datorn för att få de flesta symbol filerna, eller så använder man Microsofts Publika Symbolserver vilket jag rekommenderar med lokal cache (kan vara en \\unc\sökväg om man vill dela cache med andra).
Välj File -> Symbol File Path… (CTRL+S) och skriv in
SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols
Därefter ok och skapa c:\websymbols !
Klicka View -> Vervbose Output för att se lite mer info när Symbol Filerna sedan laddas.
Nu är vi redo att ladda in dumpen. Klicka File -> Open Crash Dump… (CTRL+D) leta upp memory.dmp och öppna den.
Svara Ja eller Nej till frågan om att spara Workspace, avgör om Symbol inställningarna mm ska sparas.
Nu kommer det ta ett tag innan någonting händer medans Windows hämtar hem symbolfilerna som behövs för just den här dumpen och du bör kunna se i c:\websymbols att det dyker upp filer och kataloger där.
För att få lite mer info och ha någonting att titta på kan man också i det nedersta fältet där det står kd> skriva följande:
!sym noisy
Så ska man på skärmen se t.ex
kd> !sym noisy
noisy mode – symbol prompts on
För mig såg en dump ut så här när jag laddade den
Loading Dump File [C:\WINDOWS\MEMORY.DMP]
Kernel Complete Dump File: Full address space is available
Symbol search path is: SRV*c:\symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
DBGHELP: SharedUserData – virtual symbol module
DBGHELP: nt – private symbols & lines
c:\symbols\ntoskrnl.pdb\FB1EDACE71FB4812A5D5132819D72E523\ntoskrnl.pdb
Windows XP Kernel Version 2600 (Service Pack 1) UP Free x86 compatible
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 2600.xpsp2.030422-1633
Kernel base = 0×804d4000 PsLoadedModuleList = 0×80543530
Debug session time: Wed Jun 9 07:59:01.862 2004 (GMT+2)
System Uptime: 0 days 0:01:11.472
DBGHELP: nt – private symbols & lines
c:\symbols\ntoskrnl.pdb\FB1EDACE71FB4812A5D5132819D72E523\ntoskrnl.pdb
Loading Kernel Symbols
……………………………………………………………………………………………………………………..
Loading unloaded module list
…..
Loading User Symbols
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
Use !analyze -v to get detailed debugging information.
BugCheck 24, {1902fa, f7c96638, f7c96338, 80533f7b}
Probably caused by : Pool_Corruption ( nt!ExDeferredFreePool+fb )
Followup: Pool_Corruption
———
Nu är dumpen laddad och WinDBG talar om att det är Pool_Corruption och ibland även vilken drivrutin som orsakade det.
Den talar också om att man skall använda !analyze -v för mer info.
Det är ett helt fantastiskt kommando och någonting man alltid börjar med.
Så jag skriver helt enkelt !analyze -v i kd> fönsret och för följande output
kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
NTFS_FILE_SYSTEM (24)
If you see NtfsExceptionFilter on the stack then the 2nd and 3rd
parameters are the exception record and context record. Do a .cxr
on the 3rd parameter and then kb to obtain a more informative stack
trace.
Arguments:
Arg1: 001902fa
Arg2: f7c96638
Arg3: f7c96338
Arg4: 80533f7b
Debugging Details:
——————
EXCEPTION_RECORD: f7c96638 — (.exr fffffffff7c96638)
ExceptionAddress: 80533f7b (nt!ExDeferredFreePool+0×000000fb)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000001
Parameter[1]: 00000201
Attempt to write to address 00000201
CONTEXT: f7c96338 — (.cxr fffffffff7c96338)
eax=e2015010 ebx=00000201 ecx=e2015010 edx=00000020 esi=867e2050 edi=000001ff
eip=80533f7b esp=f7c96700 ebp=f7c96740 iopl=0 nv up ei ng nz ac po cy
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010297
nt!ExDeferredFreePool+0xfb:
80533f7b 8913 mov [ebx],edx ds:0023:00000201=????????
Resetting default scope
DEFAULT_BUCKET_ID: DRIVER_FAULT
BUGCHECK_STR: 0×24
LAST_CONTROL_TRANSFER: from 8053456b to 80533f7b
STACK_TEXT:
f7c96740 8053456b e177c4a0 805321fc f7c967e4 nt!ExDeferredFreePool+0xfb [d:\nt\base\ntos\ex\pool.c @ 3853]
f7c96778 8053476f e177c850 00000000 f768e42c nt!ExFreePoolWithTag+0×413 [d:\nt\base\ntos\ex\pool.c @ 3516]
f7c96784 f768e42c e177c850 f76be8d9 f76ab2e0 nt!ExFreePool+0xb [d:\nt\base\ntos\ex\pool.c @ 3714]
f7c9678c f76be8d9 f76ab2e0 e177c850 8673e260 Ntfs!ExFreeToPagedLookasideList+0×1b [d:\xpsp1\public\ifskit\inc\ntifs.h @ 18896]
f7c967b4 f7692b70 863c3b70 f7c967e4 f7c967e9 Ntfs!NtfsDeleteFcb+0×203 [d:\xpsp1\base\fs\ntfs\strucsup.c @ 1507]
f7c96804 f76beac7 863c3b70 8673e100 e177c4a0 Ntfs!NtfsTeardownFromLcb+0×1ff [d:\xpsp1\base\fs\ntfs\strucsup.c @ 8594]
f7c9685c f768df02 863c3b70 e177c568 00000000 Ntfs!NtfsTeardownStructures+0×127 [d:\xpsp1\base\fs\ntfs\strucsup.c @ 7133]
f7c96888 f76ae8a7 863c3b70 0177c568 00000000 Ntfs!NtfsDecrementCloseCounts+0×9c [d:\xpsp1\base\fs\ntfs\strucsup.c @ 7587]
f7c96910 f76ae715 863c3b70 e177c568 e177c4a0 Ntfs!NtfsCommonClose+0×37a [d:\xpsp1\base\fs\ntfs\close.c @ 1228]
f7c969b0 804ea221 8673e020 86358cb8 867d5ae8 Ntfs!NtfsFsdClose+0×1f3 [d:\xpsp1\base\fs\ntfs\close.c @ 313]
f7c969c0 f772b42d 804ea221 8671c020 86358cb8 nt!IopfCallDriver+0×31 [d:\nt\base\ntos\io\iomgr\iosubs.c @ 2268]
f7c969c4 804ea221 8671c020 86358cb8 86358e24 sr!SrPassThrough+0×2f [d:\xpsp1\admin\pchealth\sr\kernel\dispatch.c @ 263]
f7c96a8c f768d738 86759bf8 863c3b00 f76ac6b8 nt!IopfCallDriver+0×31 [d:\nt\base\ntos\io\iomgr\iosubs.c @ 2268]
f7c96a98 f76ac6b8 863c3b70 e166ecc8 e166ecc8 Ntfs!NtfsAcquireResourceExclusive+0×1d [d:\xpsp1\base\fs\ntfs\ntfsproc.h @ 4057]
f7c96bdc 804ea221 863ad230 86358cb8 86358cb8 Ntfs!NtfsAcquireExclusiveFcb+0×40 [d:\xpsp1\base\fs\ntfs\resrcsup.c @ 1100]
f7c96c10 8054a8c9 866efae8 8673e020 863ad230 nt!IopfCallDriver+0×31 [d:\nt\base\ntos\io\iomgr\iosubs.c @ 2268]
f7c96c24 80596675 005dc338 865dc320 00000000 nt!FsRtlReleaseFileForCcFlush+0×185 [d:\nt\base\ntos\fsrtl\fastio.c @ 3322]
f7c96c40 80516027 865dc338 00000000 806abfac nt!ObpRemoveObjectRoutine+0xdd [d:\nt\base\ntos\ob\obref.c @ 2510]
f7c96c64 80500d4d 865dc6f8 865dc728 e177bc50 nt!ObfDereferenceObject+0×5d [d:\nt\base\ntos\ob\obref.c @ 2258]
f7c96c88 8050161f e1776840 865dc6fc 865dc6f8 nt!MiSegmentDelete+0xdb [d:\nt\base\ntos\mm\sectsup.c @ 306]
f7c96d4c 80502230 005dc6f8 00000000 80543b78 nt!MiCleanSection+0×681 [d:\nt\base\ntos\mm\sectsup.c @ 1947]
f7c96d90 8050234a 00000000 867b1020 00000000 nt!MiRemoveUnusedSegments+0×894 [d:\nt\base\ntos\mm\sectsup.c @ 4183]
f7c96dac 805aa2b6 00000000 00000000 00000000 nt!MiDereferenceSegmentThread+0×5e [d:\nt\base\ntos\mm\sectsup.c @ 880]
f7c96ddc 805319c6 805022ec 00000000 00000000 nt!PspSystemThreadStartup+0×34 [d:\nt\base\ntos\ps\create.c @ 2183]
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0×16 [D:\nt\base\ntos\ke\i386\threadbg.asm @ 85]
FOLLOWUP_IP:
nt!ExDeferredFreePool+fb [d:\nt\base\ntos\ex\pool.c @ 3853]
80533f7b 8913 mov [ebx],edx
SYMBOL_STACK_INDEX: 0
FOLLOWUP_NAME: Pool_Corruption
SYMBOL_NAME: nt!ExDeferredFreePool+fb
MODULE_NAME: Pool_Corruption
IMAGE_NAME: Pool_Corruption
DEBUG_FLR_IMAGE_TIMESTAMP: 0
STACK_COMMAND: .cxr fffffffff7c96338 ; kb
FAILURE_BUCKET_ID: 0×24_nt!ExDeferredFreePool+fb
BUCKET_ID: 0×24_nt!ExDeferredFreePool+fb
Followup: Pool_Corruption
———
Bli inte rädda för all information, text, minnesaddresser! Det ni troligen endast behöver kika efter är följande:
IMAGE_NAME: drivruting.sys
De flesta bluescreens sker pga en drivrutin och i många fall visas det direkt här vilken drivis det är.
Där slutar den här introductionen. I säg 7 fall av 10 kommer ni kunna se vad som orsakade blåskärmen genom ovanstående.
Sammanfattning:
—————–
En snabb sammanfattning av vad som behöver göras:
1. Ställ in att en full minnesdump skall skapas och konfigurera växlingfilen samt boota om.
2. Vänta på en bluescreen
3. Starta WinDBG, ställ in Symbol Path, ladda minnesdumpen
4. Skriv !analyze -v
5. Läs vad som orsakade felet.
Lite extra info:
—————–
I mitt fall ovan står det Pool_Corruption vilket inte alls är bra, det betyder att poolen, minnesområdet är korrupt och försvårar felsökandet en hel del. Windows kan helt enkelt inte riktigt tala om vilken drivrutin som försökte skriva till minnesområdet.
Och i de fallen behöver vi slå på “Pool Tagging” vilket monitorerar just sådana fel och loggar mer info om det för oss att debugga.
I ResKit finns ett tool som heter “gflags” som kan ställa in mer monitorering av systemet.
Start -> Run -> gflags -> ok
Kryssa i “Enable pool tagging”
Klicka OK och boota om.
I nästa memorydump kommer det nu finnas mer info och möjligen kommer WinDBG kunna tala om vilken drivrutin som orsakade Pool Corruption.
Notes:
——–
Om man skall ha en Pagefile som är minst +15mb eller +50mb mer än RAM varierar var man läser och vem man pratar om, jag tar det säkra före det osäkra och rekommenderar +50mb.
Uppdatera WinDBG regelbundet då det hela tiden kommer nya debug kommandon och den blir bättre på att få fram rätt orsaker med !analyze -v
Länkar:
——–
Online Crash Analysis – http://oca.microsoft.com/en/Welcome.asp
Degugging Tools for Windows – http://www.microsoft.com/whdc/devtools/debugging/default.mspx
Alla stavfel och Svengelska får ni på köpet
Mvh,
Markus Lassfolk
Rapid Response Engineer
Security Lead & Windows Platforms Team
Microsoft Product Support Services
