Ricerca tra la vecchia roba

Memory Leak

Posted: Luglio 1st, 2007 | Author: | Filed under: Programmazione | Commenti disabilitati su Memory Leak

Uno degli aspetti più importanti nella programmazione è la gestione delle risorse disponibili sulla macchina ed in particolare della cosidetta RAM dove il computer registra le variabili, se non viene gestita correttamente la allocazione di memoria a runtime può esserci la cosidetta Memory Leak. In C esiston delle chiamate della libreria standard che permettono di creare a runtime delle zone di memoria accessibili al programma per gestire variabili che incrementano la loro dimensione; sono definite nel file stdlib.h nella seguente maniera

void *calloc(size_t nmemb, size_t size);
void *malloc(size_t size);
void free(void *ptr);
void *realloc(void *ptr, size_t size);

In generale ognuna di queste funzioni alloca (in maniera simile) delle zone di memoria, tranne free() che si occupa di liberarla alla fine dell'utilizzo: una buona regola di programmazione consta nell'associare ad ogni xalloc() una free corrispondente in maniera da evitare "falle di memoria". Per sincerarsene a livello di codice è possibile usare grep in maniera da controllare quanti xalloc abbiamo usato e se ci sono le conseguenti free():

grep –color -n '(.{1,2}alloc(.+)|free(.+))'  *.c

metodo molto grezzo[1], ma utile ad avere una prima impressione del codice.

Nel mio caso sto scrivendo una applicazione server che ascolta alla porta 55555 e che permette la connessione ad un numero indefinito di client, questi possono comunicare tra loro scrivendo al server che si occupa di rispedire a tutti quanto scritto da uno (una specie di chat rudimentale). Il problema è che nel leggere il messaggio alloco ogni volta una stringa che non libero e quindi, sicuro di un memory leak, volevo sincerarmene in qualche maniera ed è qui che viene in aiuto la potenza dei programmi *nix: prima di tutto necessito di una fonte di caratteri da spedire al server[2]

 tr -dc '[:print:]' < /dev/urandom | tr * 'n' | nc localhost 55555

Nella riga sopra prendo dei valori casuali da /dev/urandom e con tr faccio passare solo i caratteri stampabili, poi non contento prendo un carattere qualsiasi (in questo caso *) e lo sostituisco con un a capo, in modo da avere un gran numero di linee; infine spedisco tutto nello stdin di netcat, il coltellino svizzero delle connessioni TCP/IP.

Passo successivo è utilizzare pmap che controlla la dimensione della memora utilizzata da un programma di cui gli passiamo il PID

watch pmap `pidof my_prog`

aggiungo watch così da avere il programma ripetuto ogni due secondi! Vi assicuro che visto il gran numero di caratteri generati dal comando precedente, vedrete il quantitativo di memoria salire vistosamente (fare la stessa cosa a mano era impensabile).

Tuttavia scopro che esiste un modo un pochino più scientifico per ottenere i nostri scopi: valgrind  che si preoccupa di controllare a run time i possibili deficit della nostra applicazione: per avviarlo usarlo tramite

valgrind –leak-check=yes my_prog arg1 arg2 …

dove argx sono gli (eventuali) argomenti da passare a my_prog.

 


 

[1] – Non è perfetto in quanto anche righe di commento del tipo malloc() vengono stampate, ma non ho voglia adesso di studiarmi le regex.

[2] – Questo fantastico collage di comandi è stata ispirata da questa pagina (presto in pdf per la gioia di grandi e piccini).

 


Comments are closed.