GNU/Linux >> Tutoriales Linux >  >> Linux

Leer la memoria del proceso vivo sin interrumpirlo

Desde la versión 3.2 del kernel. Puede usar la llamada al sistema process_vm_readv para leer la memoria del proceso sin interrupción.

ssize_t process_vm_readv(pid_t pid,
                                const struct iovec *local_iov,
                                unsigned long liovcnt,
                                const struct iovec *remote_iov,
                                unsigned long riovcnt,
                                unsigned long flags);

Estas llamadas al sistema transfieren datos entre el espacio de direcciones del proceso que llama ("el proceso local") y el proceso identificado por pid ("el proceso remoto"). Los datos se mueven directamente entre los espacios de direcciones de los dos procesos, sin pasar por el espacio del kernel.


Para el proceso 1234, puede obtener su mapa de memoria leyendo secuencialmente /proc/1234/maps (un pseudoarchivo textual) y leer la memoria virtual, p. read(2)-ing o mmap(2)-ing segmentos apropiados del /proc/1234/mem pseudo-archivo disperso.

Sin embargo, creo que no puedes evitar algún tipo de sincronización (quizás con ptrace(2), como gdb lo hace), ya que el proceso 1234 puede (y lo hace) alterar su espacio de direcciones en cualquier momento (con mmap y llamadas al sistema relacionadas).

La situación es diferente si el proceso monitoreado 1234 no es arbitrario, pero si podría mejorarlo para comunicarse de alguna manera con el proceso de monitoreo.

No estoy seguro de entender por qué preguntas esto. Y gdb es capaz de watch alguna ubicación sin detener el proceso.


Si tiene acceso de root y está en un sistema Linux, puede usar el siguiente script de Linux (adaptado de la excelente respuesta de Gilles en unix.stackexchange.com y la respuesta dada originalmente en la pregunta anterior, pero que incluye SyntaxErrors y no es pythonic):

#!/usr/bin/env python

import re
import sys

def print_memory_of_pid(pid, only_writable=True):
    """ 
    Run as root, take an integer PID and return the contents of memory to STDOUT
    """
    memory_permissions = 'rw' if only_writable else 'r-'
    sys.stderr.write("PID = %d" % pid)
    with open("/proc/%d/maps" % pid, 'r') as maps_file:
        with open("/proc/%d/mem" % pid, 'r', 0) as mem_file:
            for line in maps_file.readlines():  # for each mapped region
                m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r][-w])', line)
                if m.group(3) == memory_permissions: 
                    sys.stderr.write("\nOK : \n" + line+"\n")
                    start = int(m.group(1), 16)
                    if start > 0xFFFFFFFFFFFF:
                        continue
                    end = int(m.group(2), 16)
                    sys.stderr.write( "start = " + str(start) + "\n")
                    mem_file.seek(start)  # seek to region start
                    chunk = mem_file.read(end - start)  # read region contents
                    print chunk,  # dump contents to standard output
                else:
                    sys.stderr.write("\nPASS : \n" + line+"\n")

if __name__ == '__main__': # Execute this code when run from the commandline.
    try:
        assert len(sys.argv) == 2, "Provide exactly 1 PID (process ID)"
        pid = int(sys.argv[1])
        print_memory_of_pid(pid)
    except (AssertionError, ValueError) as e:
        print "Please provide 1 PID as a commandline argument."
        print "You entered: %s" % ' '.join(sys.argv)
        raise e

Si guarda esto como write_mem.py, puede ejecutar esto (con python2.6 o 2.7) o temprano en python2.5 (si agrega from __future__ import with_statement ) como:

sudo python write_mem.py 1234 > pid1234_memory_dump

para volcar la memoria pid1234 en el archivo pid1234_memory_dump.


Linux
  1. ¿No se puede eliminar el proceso de Gedit desde su Pid?

  2. Linux:¿Obtener información sobre el uso de memoria de un proceso de /proc/pid/smaps?

  3. ¿Qué proceso tiene Pid 0?

  4. ¿Cómo identificar un proceso que no tiene Pid?

  5. Definición de una variable con o sin exportación

Cómo encontrar el nombre del proceso a partir de su PID

tiempo de espera sin matar el proceso en bash

umask actual de un proceso con <pid>

Uso máximo de memoria de un proceso

¿Cómo se informa el uso de la memoria en Linux?

Cómo obtener pid del proceso recién iniciado