Newsgroup: it.comp.os.linux.development
Titolo: Come sbirciare la memoria di un processo

Come da soggetto: come posso accedere alla memoria di un processo 
arbitrario ?
Ho sperato in /proc/<pid>/mem, ma sembra che sia una strada a senso unico, 
funziona in condizioni particolari e non è mmap-abile.
Con shmem avrei bisogno della "collaborazione" del processo da osservare.
Avete qualche altra idea ?
Mi serve per implementare ( parzialmente ) un device in user space: per 
motivi di prestazione ( vorrei evitare di copiare i buffer da un processo 
al kerne, e dal kernel all'altro processo ) ho bisogno che il processo 
"server" possa accedere ai buffer del processo "client" direttamente. 
Speravo in  una mmap su /proc/<pid-client>/mem, ma sembra che funzioni solo 
se il processo è parente e/o sottoposto a ptrace(2)...

 Avete qualche altra idea ?
si, lascia perdere: l'effettivo uso della memoria dipende dalla 
versione e dal tipo del compilatore, dal linguaggio utilizzato, dal 
kernel e da altri fattori.
pero' magari il tuo problema si puo' risolvere in altro modo, senza 
accedere alla memoria: cosa devi fare?

noname wrote:

C'e' un processo generico ( client ) che esegue una write(2) su di un 
device ( che sto scrivendo );
Questo device inoltra la richiesta ad un'altro processo (server, che sto 
sviluppando ).
Quindi ho una prima copia del buffer della write da user-space -> 
kernel-space ( client -> device ), ed una seconda copia da kernel-space -> 
user-space ( device -> server ). Il problema è questo: come posso fare ad 
evitare la doppia copia ?
Ora in kernel space non ho problemi a sepere quale è l'indirizzo del 
buffer, e potrei passarlo facilmente al server insieme al pid del client, 
ma poi cosa ci faccio ? Dovrei riuscire ad accedere all'indirizzo dello 
spazio di indirizzamento del processo client dal server. 
Ripeto: device e server li sto sviluppando io, ma il client è 
un'applicazione generica: che so 'cat' o 'StarOffice'.
Spero di essere stato chiaro.

 sto sviluppando ).
l'unico modo che vedo e' far diventare parte del server il device, in 
pratica il device agisce solo come "un'interfaccia" verso il server,   
ma ovviamente il tutto va cosi' in kernel space.
Se per te questo e' accettabile, mi sembra una cosa fattibile.

 Avete qualche altra idea ?
L'unica che mi viene senza pensare a cose turche e' usare i pthread al posto
dei processi.
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.mascanc.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**
		-<! $>cd /pub	$>more beer !>-

 ma ovviamente il tutto va cosi' in kernel space.
Evidentemente sono stato poco chiaro.
Il device *è* in kernel space. Solo che in realta' ruota la richiesta ad un 
server ( in user space ) che la esegue e ritorna il risultato sempre 
attraverso il device ( e quindi poi al client ).
user            client             server
space                 \           /
                       \         /
                        \       /
kernel                   device
space
Facendo cosi quando devo passare dei dati ( attraverso una write per 
esempio ) mi trovo costretto a fare una doppia copia dei dati:
client -> device ( copy_from_user( ) ) e  device -> server ( copy_to_user( 
) )
Se il server riuscisse ad accedere alla memoria del client direttamente 
potrei ottimizzare il trasferimento dei dati.

 direttamente potrei ottimizzare il trasferimento dei dati.
 
mmmm... senza preventivo "accordo" (socket, IPC, files...) non vedo 
altri modi

 altri modi
mi correggo: se usi un qualsiasi metodo IPC (shared memory, ad esempio) 
tra _device_ e _server_, che puoi entrambi controllare, risparmi una 
write e puoi anche mettere il server in user space, senza bisogno di 
accedere al client. per togliere anche l'ultima write, be' non ho idea
 

noname wrote:

In generale NON ho accesso al "client" ( che è un programma generico come 
StarOffice, kde, gnome o altro: non posso riscriverli tutti ! :)) ).
Inoltre il mio scopo è di scrivere il device in user space. IN fondo se ci 
pensi X funziona cosi da tanto tempo: il client si connette via socket al 
server X che comanda la scheda hardware. Solo che io non voglio usare un 
socket ma un device ( insomma voglio utilizzare open, write .... )

 
Io non ho accesso a tutti e due i processi: in particolare l'osservato è 
arbitrario. ( vedi risposta a "noname" )

 "client" direttamente.
Ti posso dire che in Windows, quando non ti va di usare OpenProcess e 
Read/WriteProcessMemory, in genere cose del genere si fanno con la 
memoria condivisa, nascondendo l'implementazione in funzioni esportate 
da dll. Tu praticamente non permetti al processo di passarti un buffer 
qualsiasi, ma lo costringi ad usare un buffer condiviso che hai già 
allocato, e gli restituisci eventuali risultati sempre in quel buffer 
(sempre in Windows il meccanismo di IPC più veloce, le porte LPC, usano 
questa tecnica). Dopodichè puoi sincronizzare il server con i client 
tramite i consueti meccanismi (semafori, mutex, ecc)

 write .... )
allora puoi fare un device a blocchi, e sperare nella cache di memoria.
altri modi senza trucchi magici che poi non funzionano su kernel 
differenti non ne vedo
comunque le IPC sono state create apposta, specie la SHM, perche' non 
ti piacciono? 
Se invece vuoi proprio usare read e write, nella parte device <-> 
server, puoi usare una pipe, che dovrebbe permetterti una buona 
condivisione di memoria

 socket ma un device ( insomma voglio utilizzare open, write .... )
Considerato quello che vuoi fare (e cestinata la risposta dei thread che
proprio non c'entravano) mi sembra che non sia una buona politica quello che
vuoi fare. La comunicazione con due copie e' il metodo piu' pulito.
Io non creerei un device ma un entry nel procfs attraverso cui
inviare/ricevere messaggi di formato predefinito.
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.mascanc.net
	**ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**
 -<! Woe to you, oh Earth and Sea, for the Devil sends the Beast with
        wrath, because He knows the time is short... !>-
                Revelations, XIII - 18

 ti piacciono?
La shared mem implica una collaborazione fra i due processi. Ma il "client" 
non sa che ha a che fare con un device "particolare"


 "client" non sa che ha a che fare con un device "particolare"
mi sa che devo fare un corso di italiano, visto che non riesco a farmi 
capire:
la shm la usi tra device e server, e risparmi una copia
il client usa le write e read dal device
se le vuoi usare anche sul server usi 2 pipe verso il device
spero sia chiaro, altrimenti amen

 la shm la usi tra device e server, e risparmi una copia
Il device e' in kernel space: non ho bisogno di condividere la memoria...
Il problema e' che il device vede alternativamente solo i due spazi di 
indirizzamento: <spazio kernel> + <spazio processo client>  o <spazio 
kernel> + <spazio processo server>. Per cui ho bisogno di appoggiare i dati 
nell'unico spazio visibile contemporaneamente, cioe' quello kernel. Da qui 
le due copie.

 attraverso il device ( e quindi poi al client ).
Con get_user() (definita in include/asm/uaccess.h) puoi mappare un pezzo
di  memoria  utente nel  kernel  address  space. Con put_user()  fai  il
contrario. Di piu` non so dirti.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
Se il  destino di un uomo  e` annegare, anneghera` anche  in un bicchier
d'acqua.
Proverbio yddish