Usando o Depurador de Kernel para localizar um vazamento de memória Kernel-Mode
O depurador de kernel determina o local preciso de um vazamento de memória no modo kernel.
Habilitar marcação de pool
Primeiro, você deve usar GFlags para habilitar a marcação de pool. GFlags está incluído nas Ferramentas de Depuração para Windows. Inicie GFlags, escolha a guia Registro do Sistema, marcar a caixa Habilitar Marcação de Pool e selecione Aplicar. Você deve reiniciar o Windows para que essa configuração entre em vigor.
No Windows Server 2003 e versões posteriores do Windows, a marcação de pool sempre está habilitada.
Determinando a marca de pool do vazamento
Para determinar qual marca de pool está associada ao vazamento, geralmente é mais fácil usar a ferramenta PoolMon para esta etapa. Para obter detalhes, consulte Usando PoolMon para localizar Kernel-Mode vazamentos de memória.
Como alternativa, você pode usar o depurador de kernel para procurar marcas associadas a grandes alocações de pool. Para fazer isso, siga este procedimento:
Recarregue todos os módulos usando o comando .reload (Módulo recarregar ).
Use a extensão !poolused . Inclua o sinalizador "4" para classificar a saída pelo uso de memória paginada:
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
Determine qual marca de pool está associada ao maior uso de memória. Neste exemplo, o driver que usa a marca "Abc" está usando a maior parte da memória — quase 34 MB. Portanto, é mais provável que o vazamento de memória esteja nesse driver.
Localizando o vazamento
Depois de determinar a marca de pool associada ao vazamento, siga este procedimento para localizar o vazamento em si:
Use o comando ed (Enter Values) para modificar o valor da variável de sistema global PoolHitTag. Essa variável global faz com que o depurador seja interrompido sempre que uma marca de pool correspondente ao valor for usada.
Defina PoolHitTag igual à marca que você suspeita ser a origem do vazamento de memória. O nome do módulo "nt" deve ser especificado para uma resolução de símbolo mais rápida. O valor da marca deve ser inserido no formato little-endian (ou seja, para trás). Como as marcas de pool são sempre quatro caracteres, essa marca é, na verdade, A-b-c-space, não apenas A-b-c. Portanto, use o seguinte comando:
kd> ed nt!poolhittag ' cbA'
Para verificar o valor atual de PoolHitTag, use o comando db (Memória de Exibição):
kd> db nt!poolhittag L4 820f2ba4 41 62 63 20 Abc
O depurador será interrompido sempre que esse pool for alocado ou liberado com a marca Abc. Sempre que o depurador for interrompido em uma dessas alocações ou operações gratuitas, use o comando de depurador kb (Display Stack Backtrace) para exibir o rastreamento de pilha.
Usando esse procedimento, você pode determinar qual residente de código na memória está superalocando o pool com a marca Abc.
Para limpar o ponto de interrupção, defina PoolHitTag como zero:
kd> ed nt!poolhittag 0
Se houver vários locais diferentes em que a memória com essa marca está sendo alocada e elas estiverem em um aplicativo ou driver que você escreveu, você poderá alterar o código-fonte para usar marcas exclusivas para cada uma dessas alocações.
Se você não puder recompilar o programa, mas quiser determinar qual dos vários locais possíveis no código está causando o vazamento, você poderá desmontar o código em cada local e usar o depurador para editar esse residente de código na memória para que cada instância use uma marca de pool distinta (e anteriormente não utilizada). Em seguida, permita que o sistema seja executado por vários minutos ou mais. Após algum tempo, interrompa novamente com o depurador e use a extensão !poolfind para localizar todas as alocações de pool associadas a cada uma das novas marcas.