Le script python rapide et sale suivant vide la mémoire d'un processus vers stdout. Cela a pour effet secondaire de charger une page ou un fichier mappé. Appelez-le comme cat_proc_mem 123 456 789où les arguments sont des ID de processus.
Ce script est complètement spécifique à Linux. Il peut être adaptable à d'autres systèmes avec une /procstructure similaire (Solaris?), Mais oubliez de l'exécuter par exemple sur * BSD. Même sous Linux, vous devrez peut-être modifier la définition c_pid_tet les valeurs de PTRACE_ATTACHet PTRACE_DETACH. Il s'agit d'un script de preuve de principe, non pas comme un exemple de bonnes pratiques de programmation. À utiliser à vos risques et périls.
Linux rend la mémoire d'un processus disponible en /proc/$pid/mem. Seules certaines plages d'adresses sont lisibles. Ces plages peuvent être trouvées en lisant les informations de mappage de mémoire dans le fichier texte /proc/$pid/maps. Le pseudo-fichier /proc/$pid/memne peut pas être lu par tous les processus autorisés à le lire: le processus lecteur doit avoir appelé 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)
Voir aussi plus d'informations sur/proc/$pid/mem .
unswap () {
cat_proc_mem "$@" >/dev/null
}
swapon/swapoff(comme le suggère la réponse actuellement acceptée), vous souhaiterez peut-être annuler l'échange de votre gestionnaire d'affichage et de tous ses enfants en vidant leurs mémoires de processus (ce qui force l'annulation de l'échange). Voir aussi «Comment forcer un processus zsh échangé à swap dedans?» Sur stackoverflow.