Olá pessoal,
Qual é o administrador ou programador em Linux (provalmente em outras plataformas também) não sofreu com memory leaks. Ah!!! Memory leaks?!!? É isso ai!!
Podemos definir que memory leaks são endereços de memória alocados mas não liberados em uma aplicação, isto é, o programador alocou X bytes de memória mas não desalocou. Uma das várias utilidades que o Valgrind nos oferece, é com certeza a análise de memory leaks.
Nesse artigo, criamos dois aplicativos escritos em C. Os dois programas irão alocar 10MB de memória, porém só 1 irá desalocar a memória solicitada. Vamos ao código:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
int i;
char *str;
for (i=0;i<10;i++){
str = malloc(1048576); /* aloca 1Mebibytes --> $ echo "1*(2^20)"| bc = 1048576 */
if ( str == NULL){
perror("Erro no malloc\n");
exit(1);
}
strcpy(str,"Alocando e liberando memória - TchelloBlog");
printf("%s\n", str);
free(str); /* libera memória */
}
return 0;
}
Nesse primeiro código, podemos visualizar que a função malloc() é chamada e depois a função free() desaloca a memória. Vejamos o que o Valgrind tem a dizer sobre isso:
$> gcc -Wall -o alloc-normal alloc-normal.c $> valgrind --tool=memcheck ./alloc-normal ==1968== Memcheck, a memory error detector ==1968== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. ==1968== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info ==1968== Command: ./alloc-normal ==1968== Alocando e liberando memória - TchelloBlog Alocando e liberando memória - TchelloBlog Alocando e liberando memória - TchelloBlog Alocando e liberando memória - TchelloBlog Alocando e liberando memória - TchelloBlog Alocando e liberando memória - TchelloBlog Alocando e liberando memória - TchelloBlog Alocando e liberando memória - TchelloBlog Alocando e liberando memória - TchelloBlog Alocando e liberando memória - TchelloBlog ==1968== ==1968== HEAP SUMMARY: ==1968== in use at exit: 0 bytes in 0 blocks ==1968== total heap usage: 10 allocs, 10 frees, 10,485,760 bytes allocated ==1968== ==1968== All heap blocks were freed -- no leaks are possible ==1968== ==1968== For counts of detected and suppressed errors, rerun with: -v ==1968== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
Preste atenção na informação exibida pelo Valgrind acima referente as 10 alocações e 10 liberações de memória.
==1968== in use at exit: 0 bytes in 0 blocks
==1968== total heap usage: 10 allocs, 10 frees, 10,485,760 bytes allocated
Vamos agora ao código comilão de memória e a execução do Valgrind:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
int i;
char *str;
for (i=0;i<10;i++){
str = malloc(1048576); /* aloca 1Mebibytes --> $ echo "1*(2^20)"| bc = 1048576 */
if ( str == NULL){
perror("Erro no malloc\n");
exit(1);
}
strcpy(str,"Com fome de memória - TchelloBlog");
printf("%s\n", str);
}
return 0;
}
$> gcc -o alloc-leak alloc-leak.c $> valgrind --tool=memcheck ./alloc-leak ==2085== Memcheck, a memory error detector ==2085== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. ==2085== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info ==2085== Command: ./alloc-leak ==2085== Com fome de memória - TchelloBlog Com fome de memória - TchelloBlog Com fome de memória - TchelloBlog Com fome de memória - TchelloBlog Com fome de memória - TchelloBlog Com fome de memória - TchelloBlog Com fome de memória - TchelloBlog Com fome de memória - TchelloBlog Com fome de memória - TchelloBlog Com fome de memória - TchelloBlog ==2085== ==2085== HEAP SUMMARY: ==2085== in use at exit: 10,485,760 bytes in 10 blocks ==2085== total heap usage: 10 allocs, 0 frees, 10,485,760 bytes allocated ==2085== ==2085== LEAK SUMMARY: ==2085== definitely lost: 10,485,760 bytes in 10 blocks ==2085== indirectly lost: 0 bytes in 0 blocks ==2085== possibly lost: 0 bytes in 0 blocks ==2085== still reachable: 0 bytes in 0 blocks ==2085== suppressed: 0 bytes in 0 blocks ==2085== Rerun with --leak-check=full to see details of leaked memory ==2085== ==2085== For counts of detected and suppressed errors, rerun with: -v ==2085== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6) $>
Novamente preste atenção na saída do Valgrind confirmando 10 alocações e informando que o programa terminou com 10MB de memória em 10 blocos.
==2085== HEAP SUMMARY:
==2085== in use at exit: 10,485,760 bytes in 10 blocks
==2085== total heap usage: 10 allocs, 0 frees, 10,485,760 bytes allocated
==2085==
==2085== LEAK SUMMARY:
==2085== definitely lost: 10,485,760 bytes in 10 blocks
Okidonki pessoal!!! Agora quando desconfiarem se aquele programa esta causando memory leak, já sabem o que fazer..
Um quebra costela tchê!
















Bem legal o artigo, parabéns. Um sugestão: é possível obter mais detalhes se o executável for compilado com “-g” pra adicionar debug. Nesse caso é bom usar o “-O0″ pra otimizaçao do GCC não bagunçar muito a numeração das linhas
Bem lembrado Silvio
Obrigado pelo comment
Marcelo parabens pelo post, é de grande utilidade detectarmos memory leaks, mas nesse caso conseguimos resolver este problema com valgrind no caso de programarmos para a plataforma nativa. Você conhece alguma outra opção para trabalhar com valgrind ou outro em sistema embarcados? Plataforma arm e no meu caso mais especifico nios.
No entando so conheço a opção de cross compilar o valgrind para a plataforma desejada ou usar o splint quando tenho o código.
Obrigado
Abraços
Caio Pereira
Olá Caio,
No site http://valgrind.org/info/platforms.html o pessoal esta com planos de fazer o port para ARM. Achei ele link http://article.gmane.org/gmane.comp.debugging.valgrind/7558 também que diz um pouco sobre o assunto.
Vou dar uma procurada e qualquer coisa coloco aqui.
Obrigado pelo comment
Abraço
“;’ I am really thankful to this topic because it really gives useful information :;-