¿Cómo puedo encontrar una pérdida de memoria de un proceso en ejecución?

19

¿Hay alguna manera, puedo encontrar la pérdida de memoria de un proceso en ejecución? Puedo usar Valgrind para encontrar pérdidas de memoria antes del inicio de un proceso. Puedo usar GDB para adjuntarlo a un proceso en ejecución. ¿Cómo podría depurar las pérdidas de memoria de un proceso en ejecución?

howtechstuffworks
fuente
Valgrind es muy útil, incluso lo llamaría intuitivo.
user400344

Respuestas:

13

Aquí hay pasos casi garantizados para encontrar quién está perdiendo la memoria:

  1. Descubra el PID del proceso que causa la pérdida de memoria.

    ps -aux
  2. capturar /proc/PID/smapsy guardar en algún archivo como BeforeMemInc.txt.

  3. Espere hasta que la memoria se incremente.
  4. capturar de nuevo /proc/PID/smapsy guardarlo tieneafterMemInc.txt
  5. encuentre la diferencia entre primero smapsy segundo smaps, por ejemplo con

    diff -u beforeMemInc.txt afterMemInc.txt

  6. anote el rango de direcciones donde aumentó la memoria, por ejemplo:

       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 GDB para volcar la memoria en el proceso en ejecución u obtenga el coredump usando gcore -o process

  8. Usé gdb en el proceso en ejecución para volcar la memoria en algún archivo.

    gdb -p PID
    dump memory ./dump_outputfile.dump 0x2b3289290000 0x2b3289343000
  9. ahora, use el stringscomando o hexdump -Cpara imprimir eldump_outputfile.dump

    strings outputfile.dump
  10. Obtiene un formulario legible donde puede ubicar esas cadenas en su código fuente.

  11. Analice su fuente para encontrar la fuga.

Jagannath Pattar
fuente
12

Creo que memleax es exactamente lo que quieres.

Depura la pérdida de memoria de un proceso en ejecución al adjuntarlo, sin volver a compilar el programa o reiniciar el proceso de destino. Es muy conveniente y adecuado para el entorno de producción.

Funciona en GNU / Linux y FreeBSD.

NOTA: Soy el autor, cualquier sugerencia es bienvenida

== EDITAR ==

Escribo otra herramienta libleak , que engancha funciones de memoria por LD_PRELOAD.

Tampoco hay necesidad de modificar el programa de destino. Aunque debe reiniciar el progreso con LD_PRELOAD, puede habilitar / deshabilitar la detección durante la ejecución.

Hay mucho menos impacto en el rendimiento ya que no hay trampa de señal.

En comparación con herramientas similares (como mtrace), imprime la pila de llamadas completa en un punto sospechoso de pérdida de memoria.

Bingzheng Wu
fuente
1
Respondo por memleax como una herramienta muy útil para monitorear cualquier fuga obvia. Los resúmenes de salida son sorprendentemente efectivos . Casi como si los escribiera si tuviera el poder de procesamiento para hacerlo manualmente. Gracias por esto
sehe
6

En Linux, puede habilitar mtrace en su programa, pero es un cambio de código.

En OpenBSD, puedes probar las estadísticas de malloc .

El comprobador de fugas de Google también puede valer la pena, y a diferencia de mtrace, puede usarlo LD_PRELOADpara evitar la compilación.

Inútil
fuente
0

Creo que sin brindar soporte para la supervisión de la asignación después del inicio del programa directamente en el código fuente, no tienes suerte. Aquí hay dos razones por las que puedo pensar:

  • Los verificadores de pila se inicializan cuando comienza el programa. Algunos ofrecen la capacidad de ajustar el tiempo exacto, pero las variables de entorno que los inician deben establecerse cuando se ejecuta el programa. Esto se debe a que observan para asegurarse de que cada asignación tenga una asignación correspondiente, y de lo contrario se perderían algunas.
  • La comprobación de montón generalmente requiere privilegios elevados, o enganches, que debe proporcionar el sistema operativo. Si esos ganchos no se proporcionan al momento del inicio del programa, los verificadores de montón no pueden aprovecharlos. No creo que los sistemas operativos brinden estos privilegios después de que se inicie el programa en cuestión.

Sin embargo, si su programa se ejecuta dentro de una máquina virtual, ese entorno puede proporcionar soporte para las asignaciones de monitoreo. Sé que Java tiene varias herramientas de supervisión de asignación y recolección de basura (como visualVM ) que se conectan a programas en ejecución o máquinas virtuales.

Chris Betti
fuente
0

IBM's Purify es probablemente la herramienta más antigua y sofisticada de todas. Marcará el número de línea en el código que causa la pérdida de memoria.

Balance de vida
fuente