PDA

Visualizza la versione completa : [C/C++] Programma che controlla i processi creati in Linux


Cell
15-07-2010, 01:20
Salve. :ciauz:

Avrei necessità di creare in C++ (o eventualmente in C) un programma che, sotto Linux, riesca a monitorare quali processi vengono creati nel sistema in un particolare lasso di tempo (ad es., da quando il programma è lanciato a quando viene stoppato, o qualcosa di simile). Per ognuno dei processi rilevati mi servirebbe anche rilevare informazioni quali il suo pid, il pid del padre, etc. Spero di essermi spiegato. Vorrei un po' qualche spunto su come potrei fare, perché sono abbastanza in alto mare. :dhò:

Suggerimenti? :dottò:

simo_us
15-07-2010, 04:10
Scusa una domanda, ma perché devi crearlo se esistono top (http://it.wikipedia.org/wiki/Top_(Unix)) e pstree (http://en.wikipedia.org/wiki/Pstree) ?
Comunque credo che un libro che tratti a fondo il funzionamento del Kernel o programmazione di sistema ti sarebbe utile.. Se vuoi chiedi :D Qui (http://www.linuxdocs.org/HOWTOs/Process-Monitor-HOWTO.html#toc1),qui (http://www.linux-tutorial.info/modules.php?name=MContent&pageid=326) e qui (http://simons-clan.com/~msimons/proc) c'é qualcosa che ti puó interessare..
Se hai bisogno chiedi pure. :ciauz:

Cell
15-07-2010, 23:17
Top e ps non sono fanno esattamente quanto ho chiesto. Io comunque ho chiesto spunti per un programma che fa questo genere di cose, ma in realtà dovrei introdurre tale funzionalità all'interno di un programma più ampio che dovrà utilizzare tali informazioni. :messner:
Tra l'altro, dovrebbe esistere qualche funzione da programma per eseguire comandi di shell o script, anche se al momento non la ricordo (anzi, se la conosci mi fai un piacere), ma pur utilizzandola non so nemmeno se sia possibile leggere da programma in una stringa (o vettore di stringhe) l'output di un comando della shell; l'unico modo che mi viene in mente è salvare l'output dei comandi della shell su un file con > e poi leggere da file (non so se conosci modo migliore).

In ogni caso, come ti dicevo, ps e top non fanno al caso mio. Il comando ps, infatti, mi dà solo una fotografia dei processi esistenti in quell'istante nel sistema, ma non mi può dire in un intervallo quali processi vengono creati. Pur volendo fare una differenza tra due esecuzioni di ps ad un primo istante t1 e ad un secondo istante t2 per capire quali processi sono stati creati nel frattempo, mi perderei l'informazione di tutti quei processi nati e morti all'interno dell'intervallo (t1,t2). Allo stesso modo, non mi può aiutare molto il comando top. :master:

Purtroppo non sono espertissimo con Linux in quanto lo uso solo occasionalmente, ma in quest'ultimo periodo lo sto utilizzando un po' più spesso per motivi di studio. Per risolvere il problema stavo infatti cercando di approfondire proprio sulle system call e sul kernel. Comunque i tuoi link, sebbene non mi abbiano aiutato nello specifico a risolvere il problema, sono interessanti e sono già una buona base di partenza per addentrarsi nel problema. Se hai consigli su titoli di libri relativi alle tematiche di cui mi parlavi (a quanto ho capito, conosci abbastanza questo genere di cose) posso provare a procurarmeli o chiedere ad amici/colleghi se li hanno.

In ogni caso, qualsiasi suggerimento o spunto per realizzare il programma di cui appunto parlavo (anche da altre persone che magari hanno più familiarità col kernel e con le system call di Linux) è ben accetto. :)

simo_us
16-07-2010, 00:35
Per fare quello che hai chiesto tu appunto ti serve conoscere le funzioni che usa il sistema per controllare i processi, (es conoscere la struct task_struct dichiarata nell'header sched.h).

Un consiglio che mi sono dimenticato di darti, é scaricarti i sorgenti di top e pstree per farti una idea piú o meno da dove partire.

Comunque, se hai bisogno di libri contattami per PM. :D Poi se vuoi ti posso aiutare con il programma. :ciauz:

simo_us
16-07-2010, 04:36
Dimenticavo, tieni d'occhio l'array "task"..

simo_us
16-07-2010, 22:48
Tra l'altro, dovrebbe esistere qualche funzione da programma per eseguire comandi di shell o script, anche se al momento non la ricordo (anzi, se la conosci mi fai un piacere), ma pur utilizzandola non so nemmeno se sia possibile leggere da programma in una stringa (o vettore di stringhe) l'output di un comando della shell; l'unico modo che mi viene in mente è salvare l'output dei comandi della shell su un file con > e poi leggere da file (non so se conosci modo migliore).
Infatti quello che ti conviene fare é farlo in shell scripting leggendo dal proc filesystem.

Cell
17-07-2010, 12:03
Francamente, non so come si fanno a vedere i sorgenti di comandi quali ps e top, tuttavia avevo provveduto ad utilizzare il comando strace per capire quali system call richiama ps. A quanto pare, il comando non fa altro che controllare la cartella proc, per cui non servirebbe neanche controllare le task_struct. Una possibile implementazione consiste quindi nel vedere quali cartelle associate a processi esistono in proc e poi, eventualmente, recuparare da ogni cartella le informazioni che servono. A dire il vero non so esattamente quali funzioni esistono per navigare nel filesystem in un programma C/C++. Inoltre, se anche riuscissi a navigare nel filesystem dovrei poter avere qualche metodo per distinguere le cartelle relative a processi (il cui nome è il pid del processo) dalle altre cartelle presenti in /proc.

Comunque ora ti scrivo anche il PM. :)

simo_us
18-07-2010, 00:34
A quanto pare, il comando non fa altro che controllare la cartella proc, per cui non servirebbe neanche controllare le task_struct.
Da user space non puoi accedere alla memoria kernel space.

Una possibile implementazione consiste quindi nel vedere quali cartelle associate a processi esistono in proc e poi, eventualmente, recuparare da ogni cartella le informazioni che servono. A dire il vero non so esattamente quali funzioni esistono per navigare nel filesystem in un programma C/C++.
Esistono anche le funzioni per accedere al proc fylesystem. Ma parliamo sempre di kernel space. Una corretta implementazione di fopen, read, fread, write e fwrite o fprintf dovrebbe, (credo), essere sufficiente. :master:
Se guardi all'interno di /proc vedrai tante cartelle nominate con un numero. bene, quel numero é un pid.. Se navighi all'interno di quelle cartelle avrai accesso alle informazioni dei processi.

Cell
18-07-2010, 01:05
Originariamente inviato da simo_us
Da user space non puoi accedere alla memoria kernel space.

Perdona l'ignoranza. C'è modo di accedere alla memoria kernel space? :confused:


Originariamente inviato da simo_us
Esistono anche le funzioni per accedere al proc fylesystem. Ma parliamo sempre di kernel space. Una corretta implementazione di fopen, read, fread, write e fwrite o fprintf dovrebbe, (credo), essere sufficiente. :master:
Se guardi all'interno di /proc vedrai tante cartelle nominate con un numero. bene, quel numero é un pid.. Se navighi all'interno di quelle cartelle avrai accesso alle informazioni dei processi.
Sì, lo so... ci sono tutte le cartelle con i pid; probabilmente dovrei fare un controllo sui nomi delle cartelle, se il nome è un numero lo posso considerare una cartella di processo. Non credo esista altro modo. Mi chiedevo però, per l'appunto, se c'è qualche funzione che permette di navigare all'ìnterno del filesystem e di recuperare i nomi di file e cartelle in una directory. Ho quasi un vago ricordo come se esistesse qualcosa del genere e che forse l'ho pure usata, ma temo di confondermi con Java, mentre a me interessa il C/C++. :shy:

In ogni caso, ciò può essere utile per implementare una ps (e, per mia curiosità personale, mi può anche interessare, per cui mi piace mantenere vivo anche quest'altro spunto di discussione), ma per implementare ciò che intendevo io, ovvero un qualcosa che controlli tutti i processi creati in un dato intervallo, credo ci voglia qualcosa di più sofisticato. Penso che ci voglia qualche comando che faccia il monitoring di tutte le system call del sistema operativo e ti dica quando c'è una system call di creazione processo, ed ottenerne così il relativo pid restituito dalla system call. Credo che system call che creano processi siano solo la fork() e la clone(), non ho idea se ne esistano altre. Il comando strace purtroppo non credo sia sufficiente, perché può al più monitorare le system call richiamate da un particolare il processo, ma non penso che possa osservare tutte le system call richiamate dal sistema operativo. :master:

simo_us
18-07-2010, 07:07
C'è modo di accedere alla memoria kernel space?
Si tramite i moduli.

n ogni caso, ciò può essere utile per implementare una ps (e, per mia curiosità personale, mi può anche interessare, per cui mi piace mantenere vivo anche quest'altro spunto di discussione), ma per implementare ciò che intendevo io, ovvero un qualcosa che controlli tutti i processi creati in un dato intervallo, credo ci voglia qualcosa di più sofisticato. Penso che ci voglia qualche comando che faccia il monitoring di tutte le system call del sistema operativo e ti dica quando c'è una system call di creazione processo, ed ottenerne così il relativo pid restituito dalla system call. Credo che system call che creano processi siano solo la fork() e la clone(), non ho idea se ne esistano altre. Il comando strace purtroppo non credo sia sufficiente, perché può al più monitorare le system call richiamate da un particolare il processo, ma non penso che possa osservare tutte le system call richiamate dal sistema operativo.
Detto concretamente per accedere alla memoria del kernel, quindi usare le funzioni stesse del sistema operativo, devi implementare la tua "applicazione come un modulo.
Per accertarti questo puoi usare l'esempio che é riportato qui (http://www.ibm.com/developerworks/linux/library/l-linux-process-management/) il cuale usa la task_struct, ma tale codice non puó essere compilato il user space. Segui le istruzioni e vedrai.
Strace serve appunto solo per sapere le syscalls che vengono richiamate da qualsiasi programma. Le funzioni per accedere ai file e cartelle si, esistono, e si possono utilizzare in user space.

Loading