Python subprocess.Popen “OSError: [Errno 12] Impossibile allocare memoria”

| | | | | | |

Nota: questa domanda è stata originariamente posta qui ma il tempo di ricompensa è scaduto anche se non è stata effettivamente trovata una risposta accettabile. Rispondo questa domanda inclusi tutti i dettagli forniti nella domanda originale.

Uno script Python esegue una serie di funzioni di classe ogni 60 secondi utilizzando sched modulo:

# sc è un'istanza sched.scheduler sc.enter(60, 1, self. doChecks, (sc, False)) 

Lo script viene eseguito come processo demonizzato utilizzando il codice qui.

Un certo numero di metodi di classe chiamati come parte di doChecks utilizzano subprocess modulo per chiamare le funzioni di sistema per ottenere le statistiche di sistema:

ps = subprocess.Popen(["ps ", "aux"], stdout=subprocess.PIPE).communicate()[0] 

Funziona bene per un periodo di tempo prima che l'intero script si arresti in modo anomalo con il seguente errore:

Fi le "/home/admin/sd-agent/checks.py", riga 436, in getProcesses File "/usr/lib/python2.4/subprocess.py", riga 533, in __init__ File "/usr/lib/python2 .4/subprocess.py", riga 835, in _get_handles OSError: [Errno 12] Impossibile allocare memoria 

L'output di free -m sul server una volta che lo script è andato in crash è:

$ free -m totale utilizzati buffer condivisi gratuiti memorizzati nella cache Mem: 894 345 549 0 0 0 -/+ buffer/cache: 345 549 Swap: 0 0 0 

Il server esegue CentOS 5.3. Non riesco a riprodurre sulle mie scatole CentOS né con altri utenti che segnalano lo stesso problema.

Ho provato una serie di cose per eseguire il debug di questo come suggerito nella domanda originale:

  1. Registrazione dell'output di free -m prima e dopo la chiamata Popen. Non vi è alcun cambiamento significativo nell'utilizzo della memoria, ad esempio la memoria non viene gradualmente utilizzata durante l'esecuzione dello script.

  2. Ho aggiunto close_fds=True alla chiamata Popen ma questo non ha fatto differenza - lo script si è ancora bloccato con lo stesso errore. Consigliato qui e qui .

  3. Ho controllato i limiti che mostravano (-1, -1) sia su RLIMIT_DATA che su RLIMIT_AS come suggerito qui.

  4. Un articolo suggerisce che la causa potrebbe essere la mancanza di spazio di scambio, ma lo scambio è effettivamente disponibile su richiesta (secondo l'host web) e questo è stato anche suggerito come causa fasulla qui.

  5. I processi sono essere chiuso perché questo è il comportamento dell'utilizzo di .communicate() come supportato dal codice sorgente Python e dai commenti qui.

Gli assegni completi sono disponibili su GitHub qui con la funzione getProcesses definita dalla riga 442. Questa viene chiamata da doChecks( ) a partire dalla riga 520.

Lo script è stato eseguito con strace con il seguente output prima dell'arresto anomalo:

recv(4, "Total Accesses: 516662 Total kBy". .., 234, 0) = 234 gettimeofday({1250893252, 887805}, NULL) = 0 write(3, "2009-08-21 17:20:52,887 - controlli"..., 91) = 91 gettimeofday({ 1250893252, 8883 62}, NULL) = 0 write(3, "2009-08-21 17:20:52,888 - controlli"..., 74) = 74 gettimeofday({1250893252, 888897}, NULL) = 0 write(3, " 21-08-2009 17:20:52,888 - controlli"..., 67) = 67 gettimeofday({1250893252, 889184}, NULL) = 0 write(3, "21-08-2009 17:20:52,889 - controlli "..., 81) = 81 close(4) = 0 gettimeofday({1250893252, 889591}, NULL) = 0 write(3, "2009-08-21 17:20:52,889 - controlli"..., 63 ) = 63 pipe([4, 5]) = 0 pipe([6, 7]) = 0 fcntl64(7, F_GETFD) = 0 fcntl64(7, F_SETFD, FD_CLOEXEC) = 0 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID |CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7f12708) = -1 ENOMEM (Impossibile allocare memoria) write(2, "Traceback (ultima chiamata più recente"..., 35) = 35 open("/usr/bin/sd-agent/ agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Impossibile allocare memoria) open("/usr/bin/sd-agent/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Impossibile allocare memoria) open( "/usr/lib/python24.zip/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo) open("/usr/lib/python2.4/agent. py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo) open("/usr/lib/python2.4/plat-linux2/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Impossibile allocare memoria) open("/usr/lib/python2.4/lib-tk/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo) open("/usr/lib/python2.4/ lib-dynload/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo) open("/usr/lib/python2.4/site-packages/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (Nessun file o directory di questo tipo) write(2, " File "/usr/bin/sd-agent/agent."..., 52) = 52 open("/home/admin/sd-agent/daemon .py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Impossibile allocare memoria) open("/usr/bin/sd-agent/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Impossibile allocare memoria) open(" /usr/lib/python24.zip/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo) open("/usr/lib/python2.4/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo) open("/usr/lib/python2.4/plat-linux2/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Impossibile allocare memoria) open("/usr/lib/python2.4/lib-tk/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo) open ("/usr/lib/python2.4/lib-dynload/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo) open("/usr/lib/python2.4/site-packages /daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (Nessun file o directory di questo tipo) write(2, " File "/home/admin/sd-agent/dae"..., 60) = 60 open(" /usr/bin/sd-agent/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Impossibile allocare memoria) open("/usr/bin/sd-agent/agent.py", O_RDONLY|O_LARGEFILE) = - 1 ENOMEM (Impossibile allocare memoria) open("/usr/lib/python24.zip/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo) open("/usr/lib/python2.4 /agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo) open("/usr/lib/python2.4/plat-linux2/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Impossibile allocare memoria) open("/usr/lib/python2.4/lib-tk/agent.py", O_RDONLY|O_LARGEFI LE) = -1 ENOENT (nessun file o directory di questo tipo) open("/usr/lib/python2.4/lib-dynload/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo) open ("/usr/lib/python2.4/site-packages/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo) write(2, " File "/usr/bin/sd-agent /agent."..., 54) = 54 open("/usr/lib/python2.4/sched.py", O_RDONLY|O_LARGEFILE) = 8 write(2, " File "/usr/lib/python2.4 /sched"..., 55) = 55 fstat64(8, {st_mode=S_IFREG|0644, st_size=4054, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7d28000 read(8, """"Un evento generalmente utile sche"..., 4096) = 4054 write(2, " ", 4) = 4 write(2, "void = action(*argument) " , 25) = 25 close(8) = 0 munmap(0xb7d28000, 4096) = 0 open("/usr/bin/sd-agent/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Impossibile allocare memoria) open ("/usr/bin/sd-agent/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Impossibile allocare memoria) open("/usr/lib/python24.zip/checks.py", O_RDONLY|O_LARG EFILE) = -1 ENOENT (nessun file o directory di questo tipo) open("/usr/lib/python2.4/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo) open("/usr /lib/python2.4/plat-linux2/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Impossibile allocare memoria) open("/usr/lib/python2.4/lib-tk/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo) open("/usr/lib/python2.4/lib-dynload/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo ) open("/usr/lib/python2.4/site-packages/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo) write(2, " File "/usr/bin/sd -agent/checks"..., 60) = 60 open("/usr/bin/sd-agent/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Impossibile allocare memoria) open("/usr/bin /sd-agent/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Impossibile allocare memoria) open("/usr/lib/python24.zip/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No tale file o directory) open("/usr/lib/python2.4/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOE NT (nessun file o directory di questo tipo) open("/usr/lib/python2.4/plat-linux2/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Impossibile allocare memoria) open("/usr/lib/ python2.4/lib-tk/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo) open("/usr/lib/python2.4/lib-dynload/checks.py", O_RDONLY |O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo) open("/usr/lib/python2.4/site-packages/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (nessun file o directory di questo tipo) write(2, " File "/usr/bin/sd-agent/checks"..., 64) = 64 open("/usr/lib/python2.4/subprocess.py", O_RDONLY|O_LARGEFILE) = 8 write (2, " File "/usr/lib/python2.4/subpr"..., 65) = 65 fstat64(8, {st_mode=S_IFREG|0644, st_size=39931, ...}) = 0 mmap2(NULL , 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7d28000 read(8, "# subprocess - Subprocesses with"..., 4096) = 4096 read(8, "lso, l'attributo newlines di t" ..., 4096) = 4096 read(8, "codice < 0: print >>sys.st"..., 4096) = 4096 read(8, "alse non esiste su 2.2.0 try"..., 4096) = 4096 read(8, " p2cread # c2pread <-"..., 4096) = 4096 write(2, " ", 4) = 4 write(2, "errread, errwrite) ", 19) = 19 close(8) = 0 munmap(0xb7d28000, 4096) = 0 open("/usr/lib/python2.4/subprocess.py", O_RDONLY|O_LARGEFILE) = 8 write(2, " File "/usr/lib/python2.4/subpr"..., 71) = 71 fstat64(8, {st_mode=S_IFREG|0644, st_size=39931, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7d28000 read(8, "# subprocess - Sottoprocessi con"..., 4096) = 4096 read(8, "lso, l'attributo newlines di t"..., 4096) = 4096 read(8, "code < 0: print >>sys .st"..., 4096) = 4096 read(8, "alse non esiste su 2.2.0 try"..., 4096) = 4096 read(8, " p2cread # c2pread <-"..., 4096) = 4096 read(8, "table(self, handle): "..., 4096) = 4096 read(8, "rrno using _sys_errlist (o siml"..., 4096) = 4096 read(8, " p2cwrite = Nessuno, Nessuno "..., 4096) = 4096 write(2, " ", 4) = 4 write(2, "self.pid = os.fork() ", 21) = 21 close(8) = 0 munmap(0xb7d28000, 4096) = 0 write(2, "OSError", 7) = 7 write(2, ": ", 2) = 2 write(2, "[Errno 12] Impossibile allocare memor"..., 33) = 33 write(2, " ", 1) = 1 unlink("/var/run/sd- agent.pid") = 0 close(3) = 0 munmap(0xb7e0d000, 4096) = 0 rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x589978}, {0xb89a60, [], SA_RESTORER, 0x589978}, 8) = 0 brk(0xa022000) = 0xa022000 gruppo_uscita(1) = ?