Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Nota Le istruzioni per abilitare questa funzionalità si applicano solo al WDK per Windows 8. Per Windows 8.1, questa funzionalità è stata integrata in Driver Verifier. Nei computer che eseguono Windows 8.1, utilizzare l'opzione simulazione sistematica delle risorse basse.
L'opzione di Inserzione di Errori Basati su Stack inietta guasti di risorse nei driver in modalità del kernel. Questa opzione usa un driver speciale, KmAutoFail.sys, insieme a Driver Verifier per penetrare nei percorsi di gestione degli errori del driver. Il test di questi percorsi è stato storicamente molto difficile. L'opzione Stack Based Failure Injection inserisce gli errori delle risorse in modo prevedibile, in modo da rendere riproducibili i problemi rilevati. Poiché i percorsi di errore sono facili da riprodurre, semplifica anche la verifica delle correzioni a questi problemi.
Per determinare la causa radice dell'errore, viene fornita un'estensione del debugger che consente di indicare esattamente quali errori sono stati inseriti e in quale ordine.
Quando l'opzione Stack Based Failure Injection è abilitata su un driver specifico, intercetta alcune chiamate da quel driver al kernel e Ndis.sys. L'errore di iniezione basato su stack esamina lo stack di chiamate, in particolare sulla parte dello stack di chiamate che proviene dal driver su cui è abilitato. Se questa è la prima volta che ha mai visto lo stack, la chiamata avrà esito negativo in base alla semantica di tale chiamata. In caso contrario, se ha visto la chiamata in precedenza, passerà attraverso non toccato. L'inserimento di errori basato su stack contiene la logica per affrontare il fatto che un driver può essere caricato e scaricato più volte. Riconoscerà che uno stack delle chiamate è lo stesso anche se il driver viene ricaricato in un indirizzo di memoria diverso.
Attivazione di questa opzione
Si può attivare la funzionalità di iniezione di errori basata sullo stack per uno o più driver quando si sta distribuendo un driver in un computer di test. È possibile selezionare l'opzione Stack Based Failure Injection quando si configurano le proprietà del Driver Verifier per i progetti del pacchetto driver. È necessario riavviare il computer per attivare o disattivare l'opzione Stack Based Failure Injection. È anche possibile eseguire un'utilità di test per abilitare Driver Verifier e questa funzionalità nel computer di test.
Importante Quando si attiva l'inserimento di errori basati su stack nel computer di test, assicurarsi di non selezionare anche Simulazione di risorse limitate.
Pagina delle proprietà dello strumento Verifica driver
- Apri le pagine delle proprietà del pacchetto dei driver. Fare clic con il pulsante destro del mouse sul progetto del pacchetto driver in Esplora soluzioni e selezionare Proprietà.
- Nelle pagine delle proprietà per il pacchetto driver, fare clic su Proprietà configurazione, fare clic su Installazione del drivere quindi su Verificatore del driver.
- Selezionare Enable Driver Verifier. Quando si abilita Driver Verifier nel computer di test, è possibile scegliere di abilitare Driver Verifier per tutti i driver nel computer, solo per il progetto driver o per un elenco di driver specificati.
- In Injector basato su stack, spuntare Inserimento errori in base allo stack (Stack Based Failure Injection).
- Fare clic su Applica o OK.
- Per altre informazioni, vedere Distribuzione di un driver in un computer di test. Per attivare questa opzione, è necessario riavviare il computer di test.
Utilizzo del test di abilitazione e disabilitazione di Driver Verifier
È anche possibile abilitare Driver Verifier eseguendo un test di utilità. Seguire le istruzioni descritte in Come testare un driver in fase di esecuzione usando Visual Studio. Nella categoria di test Tutti i test\Driver Verifier selezionare i test Abilita la verifica driver (possibile riavvio richiesto) e Disabilita la verifica driver (possibile riavvio necessario).
Selezionare le opzioni di Driver Verifier cliccando sul nome del test Abilita Driver Verifier (potrebbe essere necessario riavviare) nella finestra Driver Test Group.
Selezionare (seleziona) Inserimento errori basato su stack.
Dopo aver aggiunto questi test a un gruppo di test, è possibile salvare il gruppo di test. Per abilitare l'iniezione di errori basata su stack, eseguire il test "Attiva Verifica Driver" (potrebbe essere necessario il riavvio) sul computer che hai configurato per il test.
Per disattivare Driver Verifier, eseguire il Disable Driver Verifier (possibile riavvio necessario) test.
Utilizzo dell'opzione di Failure Injection basata su stack
Una considerazione importante quando si esegue il test con l'inserimento di errori basati su stack è che la maggior parte dei bug rilevati comporterà un controllo dei bug. Questo potrebbe rivelarsi piuttosto fastidioso se il driver è un driver avviato durante il boot. Per questo motivo, si disabiliterà automaticamente l'iniezione dei guasti basata su stack se il Driver Verifier è disabilitato. Ciò significa che è possibile disabilitare l'iniezione di errori basata su stack all'avvio dal debugger, disabilitando Driver Verifier utilizzando il comando !verifier –disable.
Se possibile, per i test iniziali con Stack Based Failure Injection, configurare il driver in modo che non venga caricato in fase di avvio. È quindi possibile eseguire alcuni semplici test di caricamento e scaricamento. Molti dei bug rilevati da Stack Based Failure Injection si verificano durante l'inizializzazione o il rilascio. Caricare e scaricare ripetutamente il driver è un buon modo per trovarli.
Dopo aver risolto eventuali correzioni necessarie per ottenere il completamento dei test di scaricamento del carico, è possibile passare a test basati su IOCTL, test funzionali completi e infine test di stress. In generale, se si segue questa progressione di test, non si scopriranno molti nuovi problemi durante i test di stress perché la maggior parte dei percorsi di codice sarà già stata eseguita prima di questo.
Utilizzo dell'estensione del debugger Stack Based Failure Injection (SBFI)
La maggior parte dei problemi riscontrati con l'inserimento degli errori basati su stack genera controlli di bug. Per aiutare a determinare la causa di questi bug di codice, il WDK fornisce l'estensione del debugger Stack Based Failure Injection e i simboli necessari. La procedura di installazione installerà entrambi nel sistema del debugger. Il percorso predefinito è C:\Programmi (x86)\Windows Kits\8.0\Debuggers\<arch>.
Per eseguire l'estensione del debugger
Dal prompt dei comandi del debugger digitare il comando seguente: !<percorso>\kmautofaildbg.dll.autofail. Ad esempio, supponendo che le estensioni del debugger siano installate in c:\dbgext e che kmautofail.pdb si trovi nel percorso del simbolo, immettere il comando seguente:
!c:\dbgext\kmautofaildbg.dll.autofail
In questo modo, verranno scaricate informazioni nel debugger che mostreranno gli stack delle chiamate degli errori più recenti iniettati. Ogni voce è simile alla seguente, ricavata da un'esecuzione di test reale. Nel seguente esempio, l'iniezione di errori basata su stack è abilitata su Mydriver.sys
Sequence: 2, Test Number: 0, Process ID: 0, Thread ID: 0
IRQ Level: 2, HASH: 0xea98a56083aae93c
0xfffff8800129ed83 kmautofail!ShimHookExAllocatePoolWithTag+0x37
0xfffff88003c77566 mydriver!AddDestination+0x66
0xfffff88003c5eeb2 mydriver!ProcessPacketDestination+0x82
0xfffff88003c7db82 mydriver!ProcessPacketSource+0x8b2
0xfffff88003c5d0d8 mydriver!ForwardPackets+0xb8
0xfffff88003c81102 mydriver!RoutePackets+0x142
0xfffff88003c83826 mydriver!RouteNetBufferLists+0x306
0xfffff88003c59a76 mydriver!DeviceSendPackets+0x156
0xfffff88003c59754 mydriver!ProcessingComplete+0x4a4
0xfffff88001b69b81 systemdriver2!ProcessEvent+0x1a1
0xfffff88001b3edc4 systemdriver1!CallChildDriver+0x20
0xfffff88001b3fc0a systemdriver1!ProcessEvent+0x3e
0xfffff800c3ea6eb9 nt!KiRetireDpcList+0x209
0xfffff800c3ea869a nt!KiIdleLoop+0x5a
Nella parte superiore dell'output, il numero di sequenza conta il numero di errori inseriti. Questo esempio mostra il secondo errore inserito durante l'esecuzione del test. L'ID del processo è 0, quindi questo è il processo di sistema. IRQL è 2, quindi viene chiamato a livello di distribuzione.
Dallo stack KmAutoFail è il driver di inserimento degli errori in base allo stack. Il nome della funzione KmAutoFail indica quale chiamata di funzione da Mydriver.sys è stata intercettata e iniettato un errore. In questo caso, la funzione non riuscita è stata ExAllocatePoolWithTag. Tutte le funzioni in KmAutoFail che intercettano le chiamate a Ntoskrnl.sys o Ndis.sys usano questa convenzione di denominazione. Verrà quindi visualizzato lo stack di chiamate con il driver sottoposto a test (Mydriver.sys). Si tratta della parte dello stack di chiamate usata per determinare l'univocità dello stack. Di conseguenza, ogni voce dumpata dall'estensione del debugger sarà univoca in questa specifica parte dello stack di chiamate. Il resto dello stack di chiamate indica chi ha chiamato il driver. L'importanza principale di questo è se il driver viene chiamato dalla modalità utente (tramite un IOCTL) o da un driver in modalità kernel.
Si noti che se un driver ha restituito un errore dalla routine DriverEntry , un tentativo di ricaricamento avverrà normalmente in una posizione di memoria diversa. In tal caso, lo stack di chiamate dalla posizione precedente conterrà probabilmente "immondizia" anziché le informazioni sullo stack del driver. Ma questo non è un problema; indica che il driver ha gestito correttamente l'errore inserito.
La prossima voce mostra una chiamata al driver tramite un IOCTL dalla modalità utente. Prendere nota dell'ID del processo e del livello IRQ. Poiché Mydriver.sys è un driver di filtro NDIS, l'IOCTL è passato attraverso Ndis.sys. Si noti che nt! NtDeviceIoControlFile si trova nello stack. Qualsiasi test eseguito sul driver che usa IOCTLs eseguirà questa funzione.
Sequence: 5, Test Number: 0, Process ID: 2052, Thread ID: 4588
IRQ Level: 0, HASH: 0xecd4650e9c25ee4
0xfffff8800129ed83 kmautofail!ShimHookExAllocatePoolWithTag+0x37
0xfffff88003c6fb39 mydriver!SendMultipleOids+0x41
0xfffff88003c7157b mydriver!PvtDisconnect+0x437
0xfffff88003c71069 mydriver!NicDisconnect+0xd9
0xfffff88003ca3538 mydriver!NicControl+0x10c
0xfffff88003c99625 mydriver!DeviceControl+0x4c5
0xfffff88001559d93 NDIS!ndisDummyIrpHandler+0x73
0xfffff88001559339 NDIS!ndisDeviceControlIrpHandler+0xc9
0xfffff800c445cc96 nt!IovCallDriver+0x3e6
0xfffff800c42735ae nt!IopXxxControlFile+0x7cc
0xfffff800c4274836 nt!NtDeviceIoControlFile+0x56
0xfffff800c3e74753 nt!KiSystemServiceCopyEnd+0x13
Analisi dei Risultati dell'Inserimento di Errori Basato su Stack
Stai eseguendo i test sul tuo driver, e improvvisamente incontri un problema. Molto probabilmente questo era un controllo dei bug, ma poteva anche perché il computer non rispondeva. Come si trova la causa? Supponendo che si tratti di un controllo di bug, usare prima l'estensione precedente per trovare l'elenco degli errori inseriti, quindi usare il comando debugger: !analyze –v.
Il controllo dei bug più comune è causato dal mancato controllo dell'esito positivo di un'allocazione. In questo caso, lo stack dell'analisi del controllo dei bug è probabilmente quasi identico a quello dell'ultimo errore inserito. A un certo punto dopo l'allocazione non riuscita (spesso la riga immediatamente successiva), il driver accederà al puntatore null. Questo tipo di bug è molto facile da correggere. A volte l'allocazione non riuscita è una o due posizioni più in alto nella lista, ma questo tipo è ancora molto facile da trovare e correggere.
Il secondo controllo dei bug più comune si verifica durante la pulizia. In questo caso, il driver ha probabilmente rilevato l'errore di allocazione ed è passato alla pulizia; ma durante la pulizia, il driver non ha controllato il puntatore e ha nuovamente eseguito l'accesso a un puntatore null. Un caso strettamente correlato è quello in cui la funzione di pulizia può essere invocata due volte. Se la pulizia non imposta il puntatore su una struttura su Null dopo averlo liberato, la seconda volta che viene chiamata la funzione di pulizia proverà a liberare la struttura una seconda volta, generando un controllo di bug.
Gli errori che causano la mancata risposta del computer sono più difficili da diagnosticare, ma la procedura per eseguirne il debug è simile. Questi errori sono spesso causati da problemi relativi al conteggio dei riferimenti o al blocco di selezione. Fortunatamente, Driver Verifier intercetterà molti problemi di blocchi spin prima che causino problemi. In questi casi, interrompere l'esecuzione nel debugger e usare l'estensione del debugger per effettuare il dump dell'elenco degli errori iniettati dall'iniezione di fallimenti basata sullo stack. Un rapido sguardo al codice relativo agli errori più recenti potrebbe mostrare un conteggio dei riferimenti eseguito prima dell'errore ma non rilasciato dopo. In caso contrario, cercare un thread nel driver in attesa di un blocco di rotazione o per qualsiasi conteggio dei riferimenti che è ovviamente errato.