Drivermania - Le FAQ

Eliminare gli errori dei driver delle periferiche

I miglioramenti nell’affidabilità di Windows 2000

Con Windows 2000 sono stati aggiunti dei miglioramenti nell’affidabilità, specialmente per quanto concerne il ripristino del sistema e le misure adottate dal sistema operativo per mantenere la configurazione aggiornata con i file di sistema approvati da Microsoft.

Questo mese analizziamo due funzionalità che sono state aggiunte a Windows 2000 relative alla protezione del codice di sistema nei confronti della scrittura e il Driver Verifier. Quest’ultimo serve per aiutare l’identificazione dei device driver scritti male e per consentire ai programmatori di evitare durante il processo di sviluppo i comuni errori nella programmazione dei device driver.

Codice di sistema protetto nei confronti della scrittura

Le applicazioni, il kernel Windows 2000 e i device driver funzionano con i puntatori. Un puntatore è una referenza a una locazione della memoria che viene allocata dal sistema a un programma o a un driver.

Un bug nei programmi o nei driver può provocare il danneggiamento dei puntatori, dove il programma o il driver assegna al puntatore un valore privo di significato invece di contenere un indirizzo di memoria corretto.

Altri due bug strettamente correlati sono quelli che portano alle condizioni di overrun e underrun dei buffer.

Questi bug si manifestano quando un programma o un driver pensa di indirizzare il buffer ad esso allocato, mentre invece il puntatore invece indirizza la memoria subito dopo la fine del buffer (condizione di overrun), oppure poco prima del suo inizio (condizione di underrun).

Quando un programma o un device driver utilizzano un puntatore non valido scrivono dei valori nella locazione di memoria che viene referenziata dal puntatore. In questa circostanza potrebbero sovrascrivere una parte del proprio codice o una porzione di un buffer diverso da quello previsto oppure della memoria non allocata.

In questo caso, Windows 2000 rileva l’errore e termina l’esecuzione dell’applicazione.

Se il colpevole è un device driver, il sistema operativo si blocca e visualizza una schermata blu di blocco per impedire al driver con il comportamento errato di danneggiare inavvertitamente alcuni file critici, come il Registro di Configurazione, oppure di danneggiare quelli su disco.

Se il puntatore indirizza una la locazione di memoria utilizzata da un buffer o da un programma differente e se il bug parte da un’applicazione, Windows 2000, rileva il problema o un suo effetto collaterale e termina l’esecuzione dell’applicazione.

Il sistema di protezione della memoria compiuta da Windows 2000 impedisce alle applicazioni di scrivere nella memoria di un’altra applicazione, tuttavia in modalità kernel un device driver può scrivere sulla memoria di qualsiasi altro device driver, oppure nella stessa memoria del kernel.

Nelle precedenti versioni di Windows NT, comprese NT 4.0 e NT 3.51, era difficile identificare la situazione di danneggiamento del kernel o della memoria generata da un bug di un device driver.

Windows 2000 forza una protezione della scrittura per aiutare gli amministratori dei sistemi e gli sviluppatori di device driver ad identificare il danneggiamento dei puntatori nel momento stessi in cui si verifica il problema.

Se un puntatore danneggiato referenzia il codice eseguibile, un device driver, oppure il kernel, il Memory Manager di Windows 2000 segnala l’operazione di sovrascrittura nel momento stesso in cui si verifica e - in conseguenza - sa quale driver ha generato questa violazione.

Questa capacità riduce i casi in cui il sistema non rileva immediatamente i puntatori danneggiati a quelli in cui il puntatore referenzia il buffer di memoria di un device driver diverso oppure del kernel.

Quando il sistema identifica un device driver che si comporta in modo non corretto, l’amministratore può aggiornare il driver oppure eliminarlo dal sistema.

Windows 2000 implementa la protezione del codice di sistema nella routine che carica in memoria l’immagine del kernel e i file dei device driver.

La funzione MiLoadSystemImage identifica il codice eseguibile nei file che vengono caricati e utilizza le funzionalità di gestione della memoria dell’hardware per indicare queste sezioni di memoria come protette nei confronti della scrittura.

In alcune situazioni, gli sviluppatori potrebbero avere la necessità di disattivare la protezione di Windows 2000 delle aree del codice di sistema. Per compiere questa operazione, lo sviluppatore deve impostare su 0 il valore del Registro di Configurazione HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Memory Manager\EnforceWriteProtection.

Il Driver Verifier

Una nuova funzionalità di Windows 2000, il Driver Verifier, è probabilmente il tool più potente nell’arsenale usato dal sistema operativo per migliorare l’affidabilità.

Il Driver Verifier (o più semplicemente Verifier) si comporta come il sistema di protezione della memoria. È un codice kernel di Windows 2000 che, che viene applicato a un device driver, per rilevare i bug più comuni nel momento in cui si manifestano.

Il sistema write-protected consente a Windows 2000 di rilevare le modifiche della memoria dei device driver o nel codice del kernel che danneggiano le referenze ai puntatori. Il Verifier rileva molti tipi di danni generati da puntatori danneggiati e che referenziano i buffer dei dati.

Se in NT 4.0 un device driver caratterizzato da un puntatore danneggiato crea una condizione di buffer overrun che danneggia la memoria di un altro driver, l’errore potrebbe restare non rilevato in modo indefinito, e ciò rende impossibile isolare il device driver che contiene il bug.

Grazie al Verifier, Windows 2000 è invece di solito in grado di rilevare immediatamente i bug di questo tipo. Il Driver Verifier rileva inoltre anche altri comuni errori di programmazione dei device driver.

Per configurare il Verifier e visualizzare alcuni dati statistici sulle attività compiute dal suo codice in esecuzione nel kernel, si usa la GUI Verifier (\%systemroot%\system32\verifier.ex).

La scheda delle proprietà di questa GUI e dotata di varie pagine a schede.

La scheda Modify Settings permette di specificare quali device driver devono essere verificati e quale tipo di verifica deve essere compiuta dal kernel.

Le impostazioni del Registro di Configurazione che vengono modificate dal Driver Verifier quando si scelgono le opzioni sulla scheda Modify Settings si trovano sotto HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Memory Management, e comprendono il valore REG_DWORD VerifyDriverLevel e il valore di stringa VerifyDrivers.

Il kernel di Windows 2000 interpreta VerifyDriverLevel come una maschera di bit, in cui ogni posizione al suo interno rappresenta uno dei tipi di verifica elencati nella parte destra della pagina Modify Settings.

Quando si selezionano gli specifici driver da verificare, il Verifier ne archivia i nomi in VerifyDrivers.

Un’eccezione riguarda quando si dice al Driver Verifier di verificare tutti i driver; in questo caso, VerifyDrivers viene impostato con il carattere wildcard dell’asterisco (*).

Dopo avere inserito o modificato le impostazioni del Driver Verifier, occorre riavviare il sistema. All’inizio del processo di avvio, il Memory Manager di Windows 2000 legge i valori del Verifier Registry in modo da stabilire quali driver devono essere verificati e quali opzioni del Verifier sono state attivate.

Successivamente, se è stato scelto almeno un driver per la verifica, il kernel controlla i nomi di tutti i device driver caricati in memoria, confrontandolo con l’elenco di quelli scelti per la verifica.

Per ogni device driver che appare in entrambi i luoghi, il kernel invoca la funzione MiApplyDriverVerifier, che sostituisce le referenze del driver a circa 40 funzioni kernel e Win32K.sys (il sottosistema Win32 in modalità kernel) con referenze alle loro versioni equivalenti del Verifier.

Le funzioni del kernel verso le quali MiApplyDriverVerifier ridirige i device driver sono associate ai tipi di controlli compiuti dal Driver Verifier.

Per esempio, quest’ultimo intercetta tutte le funzioni di allocazione e deallocazione dei buffer del device driver sottoposto a verifica.

Se un device driver sotto verifica utilizza di solito la funzione del kernel ExAllocatePool per allocare la memoria, al suo posto viene utilizzata la funzione VerifierAllocatePool.

Uno dei bug più comuni si verifica quando un driver accede a dati o codice paginabili e il processore su cui è in esecuzione si trova in corrispondenza di un livello IRQL (Interrupt Request Level) elevato.

Quando il codice o i dati sono paginabili, Windows 2000 può inviare i dati fuori dal file di paging della memoria.

Il sistema operativo usa i livelli IRQL per mascherare gli interrupt software o hardware.

A causa del modo in cui il Memory Manager di Windows 2000 si basa sugli interrupt hardware per servire gli errori di pagina (in altre parole, il Memory Manager deve avere accesso ai dati nel file di paging, che devono essere letti dal disco nella memoria), il sistema non è in grado di servire un errore di pagina quando aumenta il livello IRQL.

In ogni caso, quando aumenta il livello IRQL i device driver possono accedere ai dati bloccati in memoria; Windows 2000 chiama ‘non-paginati’ questo tipo di dati.

Spesso il sistema non rileva le istanze di un device driver che accede a dati paginabili mentre il processore sta utilizzando un livello IRQL elevato, dal momento che i dati paginabili utilizzati dal driver si trovano nella memoria del computer invece che nel file di paging.

Compiere il testing dei device driver alla ricerca di questo tipo di bug è particolarmente difficile, sebbene di solito questi bug si manifestino sotto forma di schermate blu con il codice di stop IRQL_NOT_LESS_OR_EQUAL (in altre parole, il livello IRQL non era minore o uguale a quello richiesto dall’operazione che è stata tentata - in questo caso, l’accesso alla memoria paginabile).

Se viene selezionata l’opzione Force IRQL Checking nell’elenco Verification Type della scheda Modify Settings, il Verifier cerca di persuadere i device driver a violare la regola dell’IRQL, in un modo che possa essere immediatamente rilevato da Windows 2000. Il Driver Verifier forza tutti i dati paginabili in modalità kernel fuori dal file di paging, ogni volta che un device driver sotto verifica alza il livello IRQL. La funzione che compie questa operazione è MmTrimAllSystemPageableMemory.

Ogni volta che un device driver sotto verifica accede alla memoria paginabile quando il livello IRQL viene elevato, il sistema rileva quindi istantaneamente la violazione e la schermata blu che ne risulta identifica il driver che contiene il bug.

Quando si attiva l’opzione I/O Verification sulla lista Verification Type, il Driver Verifier ridirige alcune funzioni legate all’I/O Manager e invocate dal driver verificato, verso le versioni Verifier delle stesse funzioni.

Le funzioni I/O Manager Verifier permettono di essere certi che i pacchetti IRP (I/O Request Packet), inviati da un device driver sotto verifica ad altri driver, siano effettivamente dei pacchetti IRP.

Queste funzioni permettono inoltre di verificare che qualsiasi device driver che riceve i pacchetti IRP da un device driver sotto verifica non alteri il livello IRQL del processore, con un’operazione che costituisce un altro errore piuttosto comune di programmazione dei device driver.

L’attivazione dell’opzione Allocation Fault Injection fa in modo che il Verifier generi delle failure casuali nelle allocazioni di memoria compiute dai device driver verificati.

In precedenza, gli sviluppatori scrivevano molti device driver nell’ipotesi che la memoria del kernel sarebbe sempre stata disponibile e che, se mai si fosse esaurita, il device driver non avrebbe dovuto preoccuparsi dal momento che il sistema sarebbe in ogni caso andato in crash.

Con Windows 2000, Microsoft ha tuttavia voluto assicurare che il sistema fosse in grado di sopravvivere a temporanee condizioni di scarsa memoria; in conseguenza, richiede che i device driver siano in grado di gestire in modo appropriato gli errori di allocazione che segnalano l’esaurimento della memoria del kernel.

Per questo motivo, a partire da sette minuti dopo l’avvio del sistema (un periodo di tempo sufficiente per superare la fase critica di inizializzazione, in cui una condizione di poca memoria potrebbe impedire il caricamento di un device driver), il Verifier inizia a generare errori a caso nelle chiamate di allocazione per i device driver che sta verificando.

Se un produttore di hardware non programma un driver in modo da gestire in modo corretto gli errori di allocazione, questo driver in definitiva compirà una referenza di memoria non valida e Windows 2000 sarà in grado di identificarlo.

L’opzione Pool Tracking nel box Verification Type non costituisce una novità di Windows 2000.

Anche NT 4.0 e NT 3.51 dispongono del pool tracking, sebbene in entrambi sistemi operativi l’unico modo per attivarlo sia quello di utilizzare il programma gflags.exe contenuto nel Windows NT Server 4.0 Resource Kit e nel Windows NT Server 3.51 Resource Kit.

In Windows 2000, quando i device driver allocano la memoria, possono specificare nelle loro richieste di allocazione un marcatore opzionale di quattro lettere.

Quando si disattiva il pool tracking, Windows 2000 ignora questo marcatore; se invece si attiva il tracking, Windows 2000 associa il marcatore alla memoria allocata dal driver. Utilizzando PoolMon, un tool fornito con il kit DDK (Device Driver Kit), lo sviluppatore può vedere quanta memoria sia stata assegnata da Windows 2000 a ciascun marcatore.

Il fatto di tenere sotto controllo l’utilizzo della memoria da parte del driver consente allo sviluppatore di rilevare le falle nella memoria: un errore che si verifica quando un driver non riesce a disallocare la memoria che non gli serve più.

In corrispondenza della scheda Pool Tracking del Driver Verifier Manager, il Verifier visualizza inoltre alcuni dati statistici generici di pool.

Special Pool è l’opzione finale di verifica contenuta nel box Verification Type. Quando la si attiva, il kernel alloca una regione della propria memoria per l’uso da parte del Verifier. Quest’ultimo ridirige le richieste di allocazione della memoria compiute dai driver sotto verifica verso una speciale area di pool, invece che verso le pool di memoria standard in modalità kernel.

Special Pool dispone di varie funzionalità che consentono a Windows 2000 di rilevare immediatamente gli errori di overrun e underrun; questa funzione compie inoltre ulteriori controlli, che non vengono di solito compiuti dal Memory Manager nel momento in cui un driver alloca o libera la memoria.

Quando un device driver alloca la memoria da Special Pool, il Verifier gli fornisce un’intera pagina. Inserisce quindi il buffer utilizzato dal device driver alla fine o all’inizio della pagina, mentre riempie la parte rimanente con una firma casuale.

Il Verifier contrassegna inoltre come non valida la memoria della pagina precedente e di quella successiva alla pagina allocata per il driver.

Il buffer Special Pool allocato dal Verifier a un device driver quando controlla gli errori di overrun. Se il device driver cerca di leggere o di scrivere al di là della fine del buffer, accede a una pagina non valida e il Memory Manager di Windows 2000 visualizza una schermata blu.

La configurazione per il rilevamento degli overrun comprende anche una certa misura di capacità di rilevamento degli underrun: quando il driver libera il proprio buffer per restituire la memoria al Verifier, quest’ultimo controlla che la firma che precede il buffer non cambi (quando Windows 2000 impone il rilevamento degli underrun, il Verifier alloca il buffer del driver all’inizio della pagina invece che alla sua fine).

Se la firma viene modificata, c’è la possibilità che il device driver abbia compiuto l’underrun del buffer e abbia scritto nella memoria al di fuori di quest’ultimo. Dal momento che la Verifier GUI non consente di attivare o di disattivare il rilevamento degli underrun, occorre pertanto impostare il valore del Registro di Configurazione HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Memory Management\PoolTagOverruns su 1 quando si desidera attivare il controllo degli underrun.

Le allocazioni Special Pool permettono inoltre di verificare che il livello IRQL del processore sia corretto nel momento in cui avviene un’allocazione o deallocazione. Questo controllo rileva un errore che viene compiuto da alcuni device driver quando allocano la memoria paginabile da un livello IRQL troppo elevato.

Special Pool può essere configurato in modo indipendente dal box Verification Type.

Windows 2000 interpreta il valore del Registro di Configurazione HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Memory Management\PoolTag come il valore REG_DWORD che rappresenta il marcatore di allocazione usato dal sistema per Special Pool.

In conseguenza, anche se il Verifier non sta verificando un device driver, quando il marcatore associato dal driver alla memoria allocata corrisponde al valore di PoolTag, il kernel alloca la memoria del driver da Special Pool. Se il valore di PoolTag viene impostato su 0x0000002A, oppure sul carattere di wildcard (*), tutta la memoria allocata dai driver viene gestita da Special Pool.

Microsoft utilizza il Verifier per controllare tutti i device driver che vengono proposti dai produttori per il testing HCL (Hardware Compatibility List).

Ciò permette di assicurare che i driver contenuti nella lista HCL siano compatibili con Windows 2000 e immuni dai comuni errori di programmazione. Microsoft sta inoltre prendendo in considerazione l’ipotesi di fare in modo che Windows 2000 attivi automaticamente il Verifier al fine di verificare negli ambienti produttivi tutti i device driver sospettati di provocare una schermata blu.

Quando viene visualizzata una schermata blu il kernel potrebbe contrassegnare il driver che pare averla provocata, in modo da verificarlo in corrispondenza del successivo riavviano della macchina.

Se in seguito il driver compie un’operazione non valida che viene rilevata dal Verifier, l’amministratore potrebbe inviare al produttore o a Microsoft un crash dump che evidenzi la presenza di un bug al suo interno.

Page heap

Microsoft ha inoltre aggiunto a Windows 2000 alcune applicazioni in modalità utente che costituiscono l’equivalente della funzionalità Special Pool del kernel.

Sebbene la funzionalità Page Heap sia stata già introdotta in NT 4.0 Service Pack 4, Microsoft ne sta ulteriormente pubblicizzando le features come una novità di Windows 2000.

Il supporto Page Heap consiste nel tool Gflags del Windows 2000 Resource Kit, che consente agli sviluppatori e agli amministratori di configurare un’applicazione in modo da essere eseguita con Page Heap (la memoria da cui compiono l’allocazione le applicazioni in modalità utente è un heap, mentre quella da cui compiono l’allocazione i device driver e il kernel viene chiamata pool).

Ogni applicazione ha un heap.

Proprio come Special Pool, anche Page Heap alloca la memoria per le applicazioni in modo che il sistema sia in grado di rilevare immediatamente gli errori di overrun e di underrun nella memoria.

Lo schema di allocazione di Page Heap opera esattamente come quello di Special Pool nella modalità kernel: le pagine che precedono e che seguono quella che contiene il buffer dell’applicazione vengono contrassegnate come non valide e il buffer viene creato alla fine (per il rilevamento delle condizioni di overrun) oppure all’inizio (per le condizioni di underrun) della pagina valida.

Un Windows NT più affidabile

La combinazione dei tool che Microsoft mette a disposizione di amministratori e sviluppatori al fine di prevenire, isolare e compiere il ripristino dagli errori delle applicazioni e dei driver è una buona ragione per passare da NT 4.0 a Windows 2000.

Il Driver Verifier in particolare avrà un effetto profondo sull’affidabilità percepita e reale di Windows 2000 e permetterà di assicurare un livello elevato di qualità del software relativamente al codice in esecuzione in modalità kernel, un settore in cui la qualità del software ha un’importanza estrema.

 



L’autore
Mark Russinovich si è laureato come Ph. D. in computer engineering presso la Carnegie Mellon University.
È coautore di molte diffuse utility per NT, tra cui NTFSDOS, NTFilemon, NTRegmon e NTRecover.
 sito Web http://www.sysinternals.com/.


Articolo pubblicato sulla Rivista mensile WINDOWS 2000 edita dal Gruppo Editoriale Duke Italia - Milano - tel.: 800.255.244
Windows 2000 è l'edizione italiana di Windows/NT Magazine edita da Duke Communications International - Colorado (USA)

Home - Driver - Utility -News - Consigli - Link  -Forum -Cerca - Recensioni

Copyright © 2001 Drivermania Tutti i diritti riservati

  Contattaci - Disclaimer