Das folgende schnelle Python-Skript speichert den Speicher eines Prozesses in stdout. Dies hat den Nebeneffekt, dass ausgelagerte Seiten oder zugeordnete Dateien geladen werden. Nennen Sie es als cat_proc_mem 123 456 789
wo die Argumente Prozess-IDs sind.
Dieses Skript ist völlig Linux-spezifisch. Es ist möglicherweise anpassbar an andere Systeme mit einer ähnlichen /proc
Struktur (Solaris?), Aber vergessen Sie nicht, es unter z. B. * BSD auszuführen. Selbst unter Linux müssen Sie möglicherweise die Definition c_pid_t
und die Werte von PTRACE_ATTACH
und ändern PTRACE_DETACH
. Dies ist ein Proof-of-Principle-Skript, das nicht als Beispiel für eine gute Programmierpraxis gedacht ist. Benutzung auf eigene Gefahr.
Linux stellt den Speicher eines Prozesses zur Verfügung als /proc/$pid/mem
. Nur bestimmte Adressbereiche sind lesbar. Diese Bereiche können durch Lesen der Speicherzuordnungsinformationen aus der Textdatei ermittelt werden /proc/$pid/maps
. Die Pseudodatei /proc/$pid/mem
kann nicht von allen Prozessen gelesen werden, die die Berechtigung zum Lesen haben: Der Reader-Prozess muss aufgerufen haben ptrace(PTRACE_ATTACH, $pid)
.
#!/usr/bin/env python
import ctypes, re, sys
## Partial interface to ptrace(2), only for PTRACE_ATTACH and PTRACE_DETACH.
c_ptrace = ctypes.CDLL("libc.so.6").ptrace
c_pid_t = ctypes.c_int32 # This assumes pid_t is int32_t
c_ptrace.argtypes = [ctypes.c_int, c_pid_t, ctypes.c_void_p, ctypes.c_void_p]
def ptrace(attach, pid):
op = ctypes.c_int(16 if attach else 17) #PTRACE_ATTACH or PTRACE_DETACH
c_pid = c_pid_t(pid)
null = ctypes.c_void_p()
err = c_ptrace(op, c_pid, null, null)
if err != 0: raise SysError, 'ptrace', err
## Parse a line in /proc/$pid/maps. Return the boundaries of the chunk
## the read permission character.
def maps_line_range(line):
m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line)
return [int(m.group(1), 16), int(m.group(2), 16), m.group(3)]
## Dump the readable chunks of memory mapped by a process
def cat_proc_mem(pid):
## Apparently we need to ptrace(PTRACE_ATTACH, $pid) to read /proc/$pid/mem
ptrace(True, int(pid))
## Read the memory maps to see what address ranges are readable
maps_file = open("/proc/" + pid + "/maps", 'r')
ranges = map(maps_line_range, maps_file.readlines())
maps_file.close()
## Read the readable mapped ranges
mem_file = open("/proc/" + pid + "/mem", 'r', 0)
for r in ranges:
if r[2] == 'r':
mem_file.seek(r[0])
chunk = mem_file.read(r[1] - r[0])
print chunk,
mem_file.close()
## Cleanup
ptrace(False, int(pid))
if __name__ == "__main__":
for pid in sys.argv[1:]:
cat_proc_mem(pid)
Siehe auch weitere Informationen über/proc/$pid/mem
.
unswap () {
cat_proc_mem "$@" >/dev/null
}
swapon
/ auszutauschenswapoff
(wie es die derzeit akzeptierte Antwort nahelegt), möchten Sie möglicherweise Ihren Display Manager und alle untergeordneten Elemente enttauschen, indem Sie deren Prozessspeicher entleeren (wodurch das Enttauschen erzwungen wird). Siehe auch „So erzwingen Sie das Einlagern eines ausgelagerten zsh-Prozesses?“ Beim Stapelüberlauf.