Compartilhar via


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:

  1. Recarregue todos os módulos usando o comando .reload (Módulo recarregar ).

  2. 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 
    
  3. 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:

  1. 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.

  2. 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' 
    
  3. 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  
    
  4. 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.