8 nov 2008

Effettuare il debug in modalità kernel - Blue Screen Crashes

Spesso quando ci viene restituita una schermata blu provocata da un crash, ci troviamo costretti a reinstallare il sistema operativo, ma contrariamente a quanto si possa pensare questa situazione che solitamente provoca panico e sconforto al personale IT-PRO è facilmente risolvibile.
In questo articolo vederemo da vicino come determinare la causa di un crash di sistema che genera una schermata blu (e un file di dump della memoria), comunemente chiamata Blue Screen Of Death (BSOD).
La stragrande maggioranza di questi memory dump possono essere analizzati dagli amministratori in pochi minuti utilizzando soltanto gli strumenti di debug.
Questi strumenti, opportunamente configurati, faranno la maggior parte del lavoro per noi.

Ecco alcuni termini con cui dobbiamo prendere confidenza prima di iniziare:
Schermata blu (Blue Screen): Quando il sistema incontra un problema hardware, incoerenza dei dati, o errore simili, è possibile visualizzare una schermata blu contenente le informazioni che possono essere utilizzate per determinare la causa dell 'errore. Queste informazioni comprendono il codice di arresto e se è stato creato un crash dump file. Esso può anche includere un elenco dei driver caricati e uno stack trace.
Crash dump file: È possibile configurare il sistema per scrivere le informazioni di un crash dump file sul disco rigido ogni volta che un codice di arresto viene generato. Il file (Memory.dmp) contiene informazioni sull'errore che il debugger può analizzare, questo file può essere grande quanto la memoria fisica del computer. Per impostazione predefinita, il file Memory.dmp si trova nella cartella Windows.
Debugger: E' un programma progettato per aiutare a rilevare, individuare e correggere gli errori in un altro programma. Il Debugger permette all'utente di analizzare l'esecuzione di un processo e dei suoi threads, il controllo della memoria, delle variabili, e di altri elementi.
Kernel Mode: La modalità in cui il processore esegue i servizi di sistema e i driver di periferica. All interfaces and CPU instructions are available, and all memory is accessible. Tutte le interfacce e le istruzioni della CPU sono disponibili, e tutta la memoria è accessibile.
Minidump file: Il minidump è una versione ridotta di un dump completo, o della memoria del kernel. Solitamente si preferisce un kernel memory dump completo, ma il debugger analizzerà un mini-dump e se possibile, darà le informazioni necessarie a risolvere il problema. Chiaramente sarà meglio analizzare un file già esistente, piuttosto che aspettare un nuovo crash della macchina.
STOP code: Il codice di errore che identifica il motivo per cui il kernel del sistema ha smesso di funzionare, nonche la prima serie di valori esadecimali visualizzata sulla schermata blu. Gli amministratori dovrebbero tener presente questo codice, e degli altri quattro codici visualizzati tra parentesi, ed identificare i driver visualizzati. Spesso, questo è tutto ciò di cui abbiamo veramente bisogno.
Symbol files: Tutte le applicazioni di sistema, driver e DLL sono costruiti in modo che le loro informazioni di debug risiedano in file separati, noti come symbol files. Non è necessario installare in locale i symbol files per il debug - il debugger li cercerà automaticamente sul sito pubblico di Microsoft.
E' importante sapere che è possibile effettuare il debug di un dump a 32 bit su un sistema a 64 bit. Quindi, se si dispone di una macchina x64, sarà necessaria solo la versione x64 del debugger per analizzare qualsiasi versione di memory.dmp. (o minidump)

Ecco i link per il download dei Debugging Tools for Windows per la versione 32 e 64bit.
http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx#a
http://www.microsoft.com/whdc/devtools/debugging/install64bit.mspx#

Una volta installato il debugger, per impostazione predefinita, tutto ciò di cui abbiamo bisogno è in: C:\Program Files\Debugging Tools for Windows (x64)
In questa directory, notiamo immediatamente un file di Help. Ci sarà molto utile in seguito per prendere confidenza con gli strumenti di debugging.
Per poter analizzare un file di crash, dobbiamo specificare la directory in cui sono archiviati i symblos file (Symbol File Path). Se la macchina su cui abbiamo installato il debugger è collegata ad internet, ci sarà possibile specificare un symbol server direttamente on line. Ad esempio inserendo come path: SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols
Creiamo la direcrory c:\websysmbols in C:. Servirà come appoggio per il download dei file necessari. In alternativa potremo scaricare i symbol package, in modo da poterli utilizzare off-line. ( http://www.microsoft.com/whdc/devtools/debugging/symbolpkg.mspx )
Per un analisi maggiormente approfondita avremo necessità di configurare il sistema operativo per generare un file di dump completo (nel caso di xp ad esempio), anzichè un immagine ridotta della memoria (64k) aka minidump. I file minidump anchessi utilizzabili per la maggior parte delle analisi si trovano nella directory c:\windows\minidump, mentre il file memory.dmp si trova nella directory windows.

image

Il debugger si avvia da /Start /Debugging Tools for Windows /WinDbg, portando in primo piano la GUI di Windows Debugger. Ne esiste anche una versione a linea di comando che si avvia con kd.exe. A meno che non si stia lavorando ad un driver l'interfaccia GUI andrà bene.

a1

Quando viene aperto un file memory.dmp, verrà aperta un'altra finestra e visualizzato un output analogo a quello riportato sotto. Se non viene specificato il server oppure la posizione dei file symbol, il debugger genererà l'errore evidenziato.

Loading Dump File [F:\Crashes\MEMORY.DMP]
Kernel Summary Dump File: Only kernel address space is available

Symbol search path is:
Executable search path is:
*** ERROR: Symbol file could not be found. Defaulted to export symbols for ntkrnlmp.exe -
Windows Server 2003 Kernel Version 3790 (Service Pack 2) MP (8 procs) Free x64
Product: Server, suite: TerminalServer SingleUserTS
Built by: 3790.srv03_sp2_gdr.080813-1204
Kernel base = 0xfffff800`01000000 PsLoadedModuleList = 0xfffff800`011d4140
Debug session time: Thu Oct 23 08:53:46.973 2008 (GMT-5)
System Uptime: 6 days 9:45:10.361
*** ERROR: Symbol file could not be found. Defaulted to export symbols for ntkrnlmp.exe -
Loading Kernel Symbols
..............................................................................................................................
Loading User Symbols
PEB is paged out (Peb.Ldr = 000007ff`fffde018). Type ".hh dbgerr001" for details
Loading unloaded module list
............................................
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

Use !analyze -v to get detailed debugging information.

BugCheck D1, {0, c, 0, 0}

*** ERROR: Module load completed but symbols could not be loaded for mssmbios.sys
***** Kernel symbols are WRONG. Please fix symbols to do analysis.

*************************************************************************
*** ***
*** ***
*** Your debugger is not using the correct symbols ***
*** ***
*** In order for this command to work properly, your symbol path ***
*** must point to .pdb files that have full type information. ***
*** ***
*** Certain .pdb files (such as the public OS symbols) do not ***
*** contain the required information. Contact the group that ***
*** provided you with these symbols if you need this command to ***
*** work. ***
*** ***
*** Type referenced: nt!_KPRCB ***
*** ***
*************************************************************************
*** ERROR: Module load completed but symbols could not be loaded for CLASSPNP.SYS

Come evidenziato in colore rosso, si nota immediatamente un problema con i Symbol file, inoltre vediamo come il debugger ci suggerisce cosa dobbiamo fare. Per risolvere il problema segnalatoci, è sufficiente andare nella finestra nella parte inferiore della pagina e digitare il comando !symfix.

Il comando appena digitato viene chiamato "bang symfix". Esso imposterà Windbg per utilizzare i symbols dalla libreria pubblica (sarà necessario un salvataggio del workspace e un restart dell'applicazione). Come abbiamo visto in precedenza, specificando prima questi server pubbilici(http://msdl.microsoft.com/download/symbols) si eviterà di passare questo comando al debugger. A titolo informativo sappiamo che la libreria pubblica di simboli non è una normale pagina web e che non è possibile accedervi attraverso un browser.

Questa volta, il software troverà i symbols necessari e potremo eseguire il debug! Quello che vedrete nella finestra di debug può variare in base al tipo di codice di arresto. In questo esempio, stiamo analizzando uno Stop 0x000000D1 (noto codice di arresto). L'output di un arresto di questo genere doverbbe restituire un output simile al seguente:

Microsoft (R) Windows Debugger Version 6.10.0002.229 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.

Loading Dump File [F:\crashes\MEMORY.DMP]
Kernel Summary Dump File: Only kernel address space is available

Symbol search path is: http://msdl.microsoft.com/download/symbols
Executable search path is: srv*
Windows Server 2003 Kernel Version 3790 (Service Pack 2) MP (8 procs) Free x64
Product: Server, suite: TerminalServer SingleUserTS
Built by: 3790.srv03_sp2_gdr.080813-1204
Machine Name:
Kernel base = 0xfffff800`01000000 PsLoadedModuleList = 0xfffff800`011d4140
Debug session time: Thu Oct 23 08:53:46.973 2008 (GMT-5)
System Uptime: 6 days 9:45:10.361
Loading Kernel Symbols
...............................................................
...............................................................
Loading User Symbols
PEB is paged out (Peb.Ldr = 000007ff`fffde018). Type ".hh dbgerr001" for details
Loading unloaded module list
............................................
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

Use !analyze -v to get detailed debugging information.

BugCheck D1, {0, c, 0, 0}

Debugger CompCtrlDb Connection::Open failed 80004005
PEB is paged out (Peb.Ldr = 000007ff`fffde018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 000007ff`fffde018). Type ".hh dbgerr001" for details
Probably caused by : HpCISSs2.sys

Followup: wintriag

A questo punto il debugger potrebbe già darci un indizio di ciò che probabilmente ha causato il problema, con la dichiarazione (che in alcuni case potrebbe anche non esseer presente):

Probably caused by :

La quasi totalità dei bugchecks vengono causati da un driver scritto in maniera non corretta. È possibile risolvere questo problema (di nuovo nella maggior parte dei casi) anche soltanto ottendo la versione più recente di un driver (e dei relativi software di installazione) dal venditore. In molte occasioni avrete avuto la necessità di dover fare un immagine ISO del Sistema Operativo per migrarlo su un hardware differente. Con questo stumento possiamo facilmente identificare i driver relati all'hw prececende che causano uno STOP del Kernel. Se invece il debugger non riesce a fornirci subito questo primo indizio, di nuovo ci suggerisce cosa fare ..

Use !Analyze -v to get detailed debugging information.

Sarà sufficiente fare clic su !Analyze-v, e saremo di nuovo in esecuzione. Il debugger fornirà ora, anche informazioni più dettagliate e un messaggio su cosa fare ... (di nuovo)

7: kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.
Arguments:
Arg1: 0000000000000000, memory referenced
Arg2: 000000000000000c, IRQL
Arg3: 0000000000000000, value 0 = read operation, 1 = write operation
Arg4: 0000000000000000, address which referenced memory

Debugging Details:
------------------

PEB is paged out (Peb.Ldr = 000007ff`fffde018). Type ".hh dbgerr001" for details
PEB is paged out (Peb.Ldr = 000007ff`fffde018). Type ".hh dbgerr001" for details

READ_ADDRESS: 0000000000000000

CURRENT_IRQL: c

FAULTING_IP:
+0
00000000`00000000 ?? ???

PROCESS_NAME: vssrvc.exe

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0xD1

TRAP_FRAME: fffffadf238fc110 -- (.trap 0xfffffadf238fc110)
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
rax=00000000fff92000 rbx=0000000000000000 rcx=00000000c0000102
rdx=00000000000007ff rsi=0000000000000000 rdi=fffff80001031095
rip=0000000000000000 rsp=fffffadf238fc2a0 rbp=0000000000000007
r8=0004969a8262692a r9=fffff800011b73e8 r10=0000000000000000
r11=fffffadf29aed450 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei ng nz na pe nc
00000000`00000000 ?? ???
Resetting default scope

LAST_CONTROL_TRANSFER: from fffff8000102e5b4 to fffff8000102e890

FAILED_INSTRUCTION_ADDRESS:
+0
00000000`00000000 ?? ???

STACK_TEXT:
fffffadf`238fbf88 fffff800`0102e5b4 : 00000000`0000000a 00000000`00000000 00000000`0000000c 00000000`00000000 : nt!KeBugCheckEx [d:\nt\base\ntos\ke\amd64\procstat.asm @ 170]
fffffadf`238fbf90 fffff800`0102d547 : fffffadf`35519260 00000000`00008000 00000000`00000100 fffffadf`292ca8cf : nt!KiBugCheckDispatch+0x74 [d:\nt\base\ntos\ke\amd64\trap.asm @ 2122]
fffffadf`238fc110 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!KiPageFault+0x207 [d:\nt\base\ntos\ke\amd64\trap.asm @ 1006]

STACK_COMMAND: kb

MODULE_NAME: HpCISSs2

IMAGE_NAME: HpCISSs2.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 4600a3fe

POOL_CORRUPTOR: HpCISSs2

FOLLOWUP_NAME: wintriag

FAILURE_BUCKET_ID: X64_POOL_CORRUPTION_HpCISSs2

BUCKET_ID: X64_POOL_CORRUPTION_HpCISSs2

OCA_CRASHES: 854 (in last 90 days)

Followup: wintriag

Il debugger, per l'ennesima volta ci suggerisce gentilmente il dafarsi. (basta cliccare su HpCISSs2 per ottenere informazioni sul driver di cui si dovrebbe aggiornare e il timestamp evidenziato sotto).

7: kd> lmvm HpCISSs2
start end module name
fffffadf`296f3000 fffffadf`29705000 HpCISSs2 (deferred)
Image path: HpCISSs2.sys
Image name: HpCISSs2.sys
Timestamp: Tue Mar 20 22:18:22 2007 (4600A3FE)
CheckSum: 00015F1F
ImageSize: 00012000
Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4

Per conferma, sarà necessario contattare il produttore di questo driver per verificare se sono stati segnalati dei problemi, e se nel frattempo è stato pubblicato un aggiornameto. Consiglio anche di effettuare una ricerca nella Microsoft Knowledge Base. Nel caso di questo esempio la seguente Kb, ci fornirà dei dettagli preziosi su come risolvere il nostro problema:

You receive a Stop error message after you install update 932755 or 941276
on an HP ProLiant server that is running Storport in Windows Server 2003
http://support.microsoft.com/default.aspx?scid=kb;EN-US;940015

Riferimenti:

http://msdn.microsoft.com/en-us/library/cc267861.aspx

http://www.osronline.com/index.cfm

http://blogs.msdn.com/ntdebugging/

http://blogs.technet.com/askcore/default.aspx

1 commento:

  1. Ciao,
    ti segnalo questo articolo di Fabio riguardo alla memoria e alle risorse Kernel:
    Kernel Memory Overview

    Aiuterà a capire meglio il debugging.

    Ciao! :)

    RispondiElimina