Uso del debugger del kernel per trovare una perdita di memoria Kernel-Mode
Il debugger del kernel determina la posizione precisa di una perdita di memoria in modalità kernel.
Abilitare l'assegnazione di tag al pool
È innanzitutto necessario usare GFlags per abilitare l'assegnazione di tag al pool. GFlags è incluso in Strumenti di debug per Windows. Avviare GFlags, scegliere la scheda Registro di sistema , selezionare la casella Abilita assegnazione tag pool e quindi selezionare Applica. Per rendere effettiva questa impostazione, è necessario riavviare Windows.
In Windows Server 2003 e versioni successive di Windows, l'assegnazione di tag al pool è sempre abilitata.
Determinazione del tag pool della perdita
Per determinare quale tag del pool è associato alla perdita, in genere è più semplice usare lo strumento PoolMon per questo passaggio. Per informazioni dettagliate, vedere Uso di PoolMon per trovare Kernel-Mode perdite di memoria.
In alternativa, è possibile usare il debugger del kernel per cercare i tag associati alle allocazioni di pool di grandi dimensioni. A tale scopo, seguire questa procedura:
Ricaricare tutti i moduli usando il comando .reload (Reload Module).
Usare l'estensione !poolused . Includere il flag "4" per ordinare l'output in base all'uso della memoria di paging:
kd> !poolused 4 Sorting by Paged Pool Consumed Pool Used: NonPaged Paged Tag Allocs Used Allocs Used Abc 0 0 36405 33930272 Tron 0 0 552 7863232 IoN7 0 0 10939 998432 Gla5 1 128 2222 924352 Ggb 0 0 22 828384
Determinare il tag del pool associato al maggior utilizzo della memoria. In questo esempio, il driver che usa il tag "Abc" usa la maggior parte della memoria, quasi 34 MB. Pertanto, la perdita di memoria è molto probabile che si trova in questo driver.
Ricerca della perdita
Dopo aver determinato il tag del pool associato alla perdita, seguire questa procedura per individuare la perdita stessa:
Usare il comando ed (Enter Values) per modificare il valore della variabile di sistema globale PoolHitTag. Questa variabile globale causa l'interruzione del debugger ogni volta che viene usato un tag del pool corrispondente al relativo valore.
Impostare PoolHitTag uguale al tag che si sospetta sia l'origine della perdita di memoria. Il nome del modulo "nt" deve essere specificato per una risoluzione dei simboli più rapida. Il valore del tag deve essere immesso in formato little-endian , ovvero all'indietro. Poiché i tag del pool sono sempre quattro caratteri, questo tag è in realtà A-b-c-space, non solo A-b-c. Usare quindi il comando seguente:
kd> ed nt!poolhittag ' cbA'
Per verificare il valore corrente di PoolHitTag, usare il comando db (Display Memory):
kd> db nt!poolhittag L4 820f2ba4 41 62 63 20 Abc
Il debugger verrà interrotto ogni volta che il pool viene allocato o liberato con il tag Abc. Ogni volta che il debugger si interrompe in una di queste allocazioni o in operazioni libere, usare il comando del debugger kb (Display Stack Backtrace) per visualizzare l'analisi dello stack.
Usando questa procedura, è possibile determinare quale codice residente in memoria sta sovrassegnando il pool con il tag Abc.
Per cancellare il punto di interruzione, impostare PoolHitTag su zero:
kd> ed nt!poolhittag 0
Se sono presenti diverse posizioni in cui viene allocata la memoria con questo tag e si trovano in un'applicazione o in un driver scritto, è possibile modificare il codice sorgente per usare tag univoci per ognuna di queste allocazioni.
Se non è possibile ricompilare il programma, ma si vuole determinare quale delle diverse posizioni possibili nel codice causa la perdita, è possibile rimuovere il codice in ogni posizione e usare il debugger per modificare questo codice residente in memoria in modo che ogni istanza usi un tag del pool distinto (e precedentemente inutilizzato). Consentire quindi l'esecuzione del sistema per diversi minuti o più. Dopo un certo periodo di tempo, eseguire di nuovo l'interruzione con il debugger e usare l'estensione !poolfind per trovare tutte le allocazioni di pool associate a ognuno dei nuovi tag.