[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: processi e /proc e confusione



On 16/03/2014 16:41, Alessandro T. wrote:
On 15/03/2014 16:15, Alessandro Baggi wrote:
  [...]

Non capisco perchè un determinato processo non è visibile ne con ps ne
in /proc ma esiste la dir della struttura del processo alla quale si
può accedere tranquillamente.

Questa cosa mi suona molto strana. Come hai fatto questo test?

Io ho fatto così:

cd /proc ; ps axo pid | sed '1d;s/[^0-9]*//' > ~/tmp/ps.txt ; \
ls --color=none -d1 [0-9]* | sort -n > ~/tmp/ls.txt ; \
diff ~/tmp/ps.txt ~/tmp/ls.txt

186,187c186,187
< 16239
< 16240
---
16241
16242

e come vedi le differenze sono causate, verosimilmente, dalla pipe nei
due comandi.

Ciao


Ciao Alessandro,
innanzi tutto grazie per la risposta.

Chiedo scusa per la lunghezza di questo post.

Ho fatto un altri test e forse si può arrivare alla conclusione.

Premetto che la macchina in questione è una macchina casalinga.

Quei pid consecutivi che risultano dal diff, come da te detto, sono risultanti dalle pipe. In questo caso credo che tutto sia nella norma, in quanto i processi sono conclusi e un "cd /proc/16239" ritorna un errore.

Il mio problema fa riferimento al fatto che il processo non è listato ne in /proc ne in ps e un "cd /proc/pid" ha successo.

Il mio primo rilevamento è stato del tutto casuale, ovvero lanciando il mio programma A. Il mio programma ha letto un pid da un file.pid. Ha provato a verificare se il pid esistesse semplicemente con un:

	ret = access("/proc/pid", F_OK)
	
(se il metodo è sbagliato accetto vivamente consigli)

e risultava che esisteva. Al momento del lancio del programma però, il programma B era disattivato quindi era quasi impossibile che quel pid fosse stato gia riutilizzato, quindi era una condizione quasi "impossibile" per quel preciso momento. Per scrupolo ho provato a verificare con ps e con ls /proc e il processo non veniva listato. Effettuando un cd /proc/pid e un ls ho trovato tutta la struttura del processo e mi sono allarmato.

Ora per far capire meglio il tutto faccio un piccolo esempio.

Esempio:

Mio programma A legge il file.pid e dice che dentro ci sta il pid 1555.
Il mio programma con la chiamata access() dice che la dir "pid" esiste e non avvia il programma B. Se do un "ps aux | grep 1555" oppure un "ls /proc | grep 1555" non ottengo nessun risultato. Questo dovrebbe indicare (almeno in buona parte) che un processo non è attivo.

ma un comando come:

	cat /proc/1555/cmdline
	kill 1555

che vanno a buon fine su un processo che non è listato mi suona molto strano.

All'inizio pensavo che il sistema fosse stato violato, ma su uno nuovo di pacca, distro diversa,senza avviare X il "problema" persiste.

Nel successivo test che ho fatto per indagare su questo comportamento ha visto coinvolti uno script.sh che lancia:

	ps aux > pidlist
	./programma

Tutto eseguito da root.
Il programma di test è scritto in C, è molto primitivo e incompleto (abbiate pietà, l'ho scritto molto in fretta), rileva solo i processi che potrebbero essere sospetti. Dato che il ps aux viene lanciato prima dell'avvio del programma di controllo, potrebbero essere stati creati altri processi di brevissima durata che appaiono in /proc ma non in ps aux (in quanto lanciato prima). Quindi potrebbero esserci dei pid validi e rimane all'utente il controllo finale, ovvero verificare che il processo pid rilevato non appaia in /proc ne in ps ma che sia possibile accederci.

Voglio anche precisare che il programma ha tempi di esecuzioni molto bassi:

# time ./proc_check.sh
....
real    0m0.060s
user    0m0.016s
sys     0m0.036s

Il programma cmq effettua alcune operazioni:

1) legge il numero massimo di processi che possono essere lanciati sul sistema.
2) legge il file pidlist
3) esegue un ciclo che va da 0 a maxpid. In questo ciclo utilizzo l'indice (c = da 0 a maxpid) come pid del processo. Per ogni ciclo, effettuo un controllo su /proc/c con access(). Se access() ritorna che il /proc/c non esiste allora il ciclo continua con il prossimo pid ottenuto dal ciclo (indice c), se invece vede che esiste, effettua un controllo sulla lista dei processi di pidlist. Se il processo viene trovato, allora continua con il processo successivo in quanto la condizione è normale, ma se non lo trova emette un alert che stampa il PID che potrebbe essere infausto. A questo punto è compito dell'utente verificare se:

1) ps aux | grep PID  (non da risultato)
2) ls /proc | grep PID (non da risultato)
3) cd /proc/PID && cat cmdline (da risultato)
4) kill PID	(da risultato)

Lanciando il programma vengono emessi 184 alert, riporto la parte
finale del file:

(tra i 184 alert potrebbero esserci alert per processi validi, l'user deve controllare)

....
pid 17873 ALERT
pid 17874 ALERT
pid 17937 ALERT
pid 17938 ALERT
pid 17939 ALERT
pid 19524 ALERT
pid 19558 ALERT
pid 19559 ALERT
pid 19562 ALERT
pid 19571 ALERT
pid 19572 ALERT
pid 19574 ALERT
pid 19603 ALERT

Prendo in esame l'ultimo processo, 19603:

# ps aux | grep 19603
root     19619  0.0  0.0   7848   876 pts/3    S+   18:45   0:00 grep 19603

# ls /proc | grep 19603
# ls /proc

non riporta il pid 19603 e provando ad accederci ottengo


root@HOSTNAME# cd /proc/19603
bash: cd: /proc/19603: File o directory non esistente
root@HOSTNAME# kill 19603
bash: kill: (19603) - Nessun processo corrispondente


Ma con il penultimo pid (19574):

root@HOSTNAME:/proc# ps aux | grep 19574
root     19836  0.0  0.0   7848   876 pts/3    S+   18:51   0:00 grep 19574
root@HOSTNAME:/proc# ls	 (lista processi ma non il 19574)
root@HOSTNAME:/proc# ls -ld 19574 (lista le informazioni legate all dir del pid con owner l'utente che l'ha avviato) root@HOSTNAME:/proc# cd 19574 (scritto manulamente perche il completamento con questo pid non listato non funziona)
root@HOSTNAME:/proc/19574# ls
attr cgroup comm cwd fd limits mem mountstats numa_maps oom_score_adj root smaps statm task autogroup clear_refs coredump_filter environ fdinfo loginuid mountinfo net oom_adj pagemap sched stack status wchan auxv cmdline cpuset exe io maps mounts ns oom_score personality sessionid stat syscall

root@HOSTNAME:/proc/19574# cat cmdline
amarokroot@HOSTNAME:/proc/19574#

root@HOSTNAME:/proc/19574# ps aux | grep amarok
1000      7689  1.3  1.7 5022948 283844 tty1   SLl  mar15  20:48 amarok
root     19913  0.0  0.0   7852   868 pts/3    S+   18:53   0:00 grep amarok

Come potete vedere, il processo amarok è 7689 mentre il nostro processo è 19574.

Amarok  è in funzione e dando un

root@HOSTNAME:/proc# kill 19574

Amarok viene chiuso e la musica finisce.

Ora come si puo vedere, amarok ha il pid a 7689 mentre è stato ucciso con un kill al pid 19574 non rilevabile con ps e in /proc.

Ma ancora non quadra.

Il pid di amarok è molto basso [7689] mentre quello rilevato è 19574. Questo potrebbe essere dovuto dal fatto che ho lasciato la macchina accesa dal giorno prima e amarok era avviato ma non faceva nulla (in sleep). Avendo avviato il play potrebbe aver creato un thread con il quale effettua il play reale.

L'unica cosa che al momento mi viene in mente (ipotesi irreale) è che amarok (e gli altri programmi individuati) ha dei thread e che il kernel gestisca i thread come dei processi (creando quindi la struttura del processo) ma non li rende visibili su /proc in modo tale che le altre utility come ps o top non possano rilevarli come processi. L'utente non vedendoli non puo considerarli e va ad effettuare il kill direttamente sul processo non andando a toccare il thread (magari la politica è: il kill deve essere effettuato sul processo e non sul thread). Questo non vuol dire che non sia possibile effettuare il kill su quel pid.


Qualcuno ha info in merito?

(scusate di nuovo per la lunghezza, ho voluto scrivere tutto il test per condividere questa esperienza).

Un saluto, Alessandro.


Reply to: