Como posso encontrar um vazamento de memória de um processo em execução?

19

Existe uma maneira, eu posso encontrar o vazamento de memória de um processo em execução? Posso usar o Valgrind para encontrar vazamentos de memória antes do início de um processo. Eu posso usar o GDB para anexá-lo a um processo em execução. Como depurar vazamentos de memória de um processo em execução?

howtechstuffworks
fonte
Valgrind é muito útil, eu diria que é intuitivo.
user400344

Respostas:

13

Aqui estão quase as etapas de garantia para encontrar quem está vazando a memória:

  1. Descubra o PID do processo que está causando o vazamento de memória.

    ps -aux
  2. capturar /proc/PID/smapse salvar em algum arquivo como BeforeMemInc.txt.

  3. espere até a memória aumentar.
  4. capturar novamente /proc/PID/smapse salvá-loafterMemInc.txt
  5. encontre a diferença entre o primeiro smapse o segundo smaps, por exemplo, com

    diff -u beforeMemInc.txt afterMemInc.txt

  6. anote o intervalo de endereços em que a memória aumentou, por exemplo:

       beforeMemInc.txt            afterMemInc.txt
    ---------------------------------------------------
    2b3289290000-2b3289343000   2b3289290000-2b3289343000  #ADDRESS
    Shared_Clean:    0 kB       Shared_Clean:    0 kB          
    Shared_Dirty:    0 kB       Shared_Dirty:    0 kB
    Private_Clean:   0 kB       Private_Clean:   0 kB
    Private_Dirty:  28 kB       Private_Dirty:  36 kB  
    Referenced:     28 kB       Referenced:     36 kB
    Anonymous:      28 kB       Anonymous:      36 kB  #INCREASE MEM
    AnonHugePages:   0 kB       AnonHugePages:   0 kB
    Swap:            0 kB       Swap:            0 kB
    KernelPageSize:  4 kB       KernelPageSize:  4 kB
    MMUPageSize:     4 kB       MMUPageSize:     4 kB
    Locked:          0 kB       Locked:          0 kB
    VmFlags: rd wr mr mw me ac  VmFlags: rd wr mr mw me ac
  7. use o GDB para despejar memória no processo em execução ou obter o coredump usando gcore -o process

  8. Eu usei o gdb no processo em execução para despejar a memória em algum arquivo.

    gdb -p PID
    dump memory ./dump_outputfile.dump 0x2b3289290000 0x2b3289343000
  9. Agora, use o stringscomando ou hexdump -Cpara imprimir odump_outputfile.dump

    strings outputfile.dump
  10. Você obtém um formulário legível onde pode localizar essas cadeias no seu código-fonte.

  11. Analise sua fonte para encontrar o vazamento.

Jagannath Pattar
fonte
12

Eu acho que memleax é exatamente o que você quer.

Ele depura o vazamento de memória de um processo em execução, anexando-o, sem recompilar o programa ou reiniciar o processo de destino. É muito conveniente e adequado para o ambiente de produção.

Funciona no GNU / Linux e FreeBSD.

NOTA: Sou o autor, qualquer sugestão é bem-vinda

== EDIT ==

Escrevo outra ferramenta libleak , que conecta funções de memória por LD_PRELOAD.

Também não há necessidade de modificar o programa de destino. Embora você precise reiniciar o progresso com LD_PRELOAD, é possível ativar / desativar a detecção durante a execução.

Há muito menos impacto no desempenho, pois não há interceptação de sinal.

Comparado com ferramentas semelhantes (como mtrace), ele imprime a pilha de chamadas completa no ponto de vazamento de memória suspeito.

Bingzheng Wu
fonte
11
Garanto o memleax como uma ferramenta muito útil para monitorar vazamentos óbvios. Os resumos de saída são surpreendentemente eficazes . Quase como eu os escreveria se tivesse o poder de processamento para fazê-lo manualmente. Obrigado por isso
sehe
6

No Linux, você pode ativar o mtrace no seu programa, mas é uma alteração de código.

No OpenBSD, você pode tentar as estatísticas do malloc .

O verificador de vazamento do Google também pode valer uma olhada e, ao contrário do mtrace, você pode usar LD_PRELOADpara evitar a recompilação.

Sem utilidade
fonte
0

Acho que sem fornecer suporte para o monitoramento da alocação após o início do programa diretamente no código-fonte, você está sem sorte. Aqui estão duas razões pelas quais posso pensar:

  • Os verificadores de heap são inicializados quando o programa é iniciado. Alguns oferecem a capacidade de ajustar o tempo exato, mas as variáveis ​​de ambiente que os iniciam devem ser definidas quando o programa é executado. Isso ocorre porque eles observam para garantir que cada alocação tenha uma desalocação correspondente e, caso contrário, perderiam algumas.
  • A verificação de heap geralmente requer privilégios elevados, ou ganchos, a serem fornecidos pelo sistema operacional. Se esses ganchos não forem fornecidos no momento do início do programa, os verificadores de pilha não poderão aproveitá-los. Não acredito que os sistemas operacionais ofereçam esses privilégios após o início do programa em questão.

Se, no entanto, seu programa estiver sendo executado dentro de uma máquina virtual, esse ambiente poderá fornecer suporte para monitorar alocações. Eu sei que o Java tem várias ferramentas de monitoramento de alocação e coleta de lixo (como o visualVM ) que se conectam à execução de programas ou VMs.

Chris Betti
fonte
0

O Purify da IBM é provavelmente a ferramenta mais antiga e sofisticada de todas. Ele marcará o número da linha no código que causa o vazamento de memória.

equilíbrio
fonte