GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Lesen des lebenden Prozessspeichers, ohne ihn zu unterbrechen

Seit der Version 3.2 des Kernels. Sie können den Systemaufruf process_vm_readv verwenden, um den Prozessspeicher ohne Unterbrechung zu lesen.

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);

Diese Systemaufrufe übertragen Daten zwischen dem Adressraum des aufrufenden Prozesses ("dem lokalen Prozess") und dem durch pid identifizierten Prozess ("dem entfernten Prozess"). Die Daten bewegen sich direkt zwischen den Adressräumen der beiden Prozesse, ohne den Kernelspace zu durchlaufen.


Für Prozess 1234 können Sie seine Speicherabbildung erhalten, indem Sie nacheinander /proc/1234/maps lesen (eine textuelle Pseudodatei) und den virtuellen Speicher lesen, z. read(2)-ing oder mmap(2)-ing entsprechende Segmente von /proc/1234/mem Sparse-Pseudo-Datei.

Ich glaube jedoch, dass Sie eine Art Synchronisation nicht vermeiden können (vielleicht mit ptrace(2), als gdb). tut), da der Prozess 1234 seinen Adressraum jederzeit ändern kann (und tut) (mit mmap &verwandte Systemaufrufe).

Die Situation ist anders, wenn der überwachte Prozess 1234 nicht willkürlich ist, sondern wenn Sie ihn verbessern könnten, um irgendwie mit dem überwachenden Prozess zu kommunizieren.

Ich bin mir nicht sicher, zu verstehen, warum Sie das fragen. Und gdb kann watch bestimmten Ort, ohne den Prozess zu stoppen.


Wenn Sie Root-Zugriff haben und sich auf einem Linux-System befinden, können Sie das folgende Linux-Skript verwenden (angepasst an Gilles hervorragende unix.stackexchange.com-Antwort und die Antwort, die ursprünglich in der obigen Frage gegeben wurde, aber SyntaxErrors enthält und nicht pythonisch ist):

#!/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

Wenn Sie dies als write_mem.py speichern, können Sie dies (mit python2.6 oder 2.7) oder früh in python2.5 (wenn Sie from __future__ import with_statement hinzufügen) ausführen ) als:

sudo python write_mem.py 1234 > pid1234_memory_dump

um den pid1234-Speicher in die Datei pid1234_memory_dump.

zu kopieren
Linux
  1. Variable mit oder ohne Export definieren

  2. Geöffnete Dateien pro Vorgang zählen

  3. Malloc unter Linux ohne Overcommitting

  4. Aktuelle umask eines Prozesses mit <pid>

  5. Maximale Speicherauslastung eines Prozesses

Kann den Gedit-Prozess nicht von seiner Pid aus beenden?

Linux – Informationen über die Speichernutzung eines Prozesses von /proc/pid/smaps abrufen?

Wie identifiziere ich einen Prozess, der keine Pid hat?

So finden Sie den Prozessnamen anhand seiner PID

Wie wird die Speichernutzung in Linux gemeldet?

Wie man einen gerade gestarteten Prozess pipi bekommt