Pouvez-vous m'aider à résoudre mon memory leak ?

Pouvez-vous m'aider à résoudre mon memory leak ? - C - Programmation

Marsh Posté le 21-04-2005 à 17:29:50    

Bonjour,
Voilà, je viens de faire un prog en C, et le problème, c'est que la mémoire qu'il utilise augmente sans arrêt. Alors j'ai lancé le programme avec valgrind, et voici ce qu'il me répond :

==13224== Memcheck, a memory error detector for x86-linux.
==13224== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al.
==13224== Using valgrind-2.4.0, a program supervision framework for x86-linux.
==13224== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al.
==13224== For more details, rerun with: -v
==13224==  
==13224==  
==13224== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 27 from 1)
==13224== malloc/free: in use at exit: 31465 bytes in 451 blocks.
==13224== malloc/free: 4120 allocs, 3669 frees, 3847254 bytes allocated.
==13224== For counts of detected errors, rerun with: -v
==13224== searching for pointers to 451 not-freed blocks.
==13224== checked 10924852 bytes.
==13224==  
==13224== 4 bytes in 1 blocks are still reachable in loss record 1 of 19
==13224==    at 0x1B90354C: malloc (vg_replace_malloc.c:130)
==13224==    by 0x1B903EFB: realloc (vg_replace_malloc.c:188)
==13224==    by 0x80490E5: add (phpwrapperd.c:151)
==13224==    by 0x80493B4: reset_configs (phpwrapperd.c:203)
==13224==    by 0x804A047: main (phpwrapperd.c:537)
==13224==  
==13224==  
==13224== 10 bytes in 2 blocks are still reachable in loss record 2 of 19
==13224==    at 0x1B90354C: malloc (vg_replace_malloc.c:130)
==13224==    by 0x8049938: get_user (phpwrapperd.c:338)
==13224==    by 0x8049B77: send_phpconfig (phpwrapperd.c:379)
==13224==    by 0x804A08D: main (phpwrapperd.c:555)
==13224==  
==13224==  
==13224== 16 bytes in 1 blocks are still reachable in loss record 3 of 19
==13224==    at 0x1B90354C: malloc (vg_replace_malloc.c:130)
==13224==    by 0x8048FFE: add (phpwrapperd.c:131)
==13224==    by 0x80493B4: reset_configs (phpwrapperd.c:203)
==13224==    by 0x804A047: main (phpwrapperd.c:537)
==13224==  
==13224==  
==13224== 16 bytes in 1 blocks are still reachable in loss record 4 of 19
==13224==    at 0x1B90354C: malloc (vg_replace_malloc.c:130)
==13224==    by 0x8049034: add (phpwrapperd.c:137)
==13224==    by 0x80493B4: reset_configs (phpwrapperd.c:203)
==13224==    by 0x804A047: main (phpwrapperd.c:537)
==13224==  
==13224==  
==13224== 20 bytes in 2 blocks are still reachable in loss record 5 of 19
==13224==    at 0x1B90354C: malloc (vg_replace_malloc.c:130)
==13224==    by 0x80499D9: get_user (phpwrapperd.c:346)
==13224==    by 0x8049B77: send_phpconfig (phpwrapperd.c:379)
==13224==    by 0x804A08D: main (phpwrapperd.c:555)
==13224==  
==13224==  
==13224== 20 bytes in 2 blocks are still reachable in loss record 6 of 19
==13224==    at 0x1B90354C: malloc (vg_replace_malloc.c:130)
==13224==    by 0x8049077: add (phpwrapperd.c:142)
==13224==    by 0x80493B4: reset_configs (phpwrapperd.c:203)
==13224==    by 0x804A047: main (phpwrapperd.c:537)
==13224==  
==13224==  
==13224== 28 bytes in 1 blocks are still reachable in loss record 7 of 19
==13224==    at 0x1B903F72: realloc (vg_replace_malloc.c:196)
==13224==    by 0x80490E5: add (phpwrapperd.c:151)
==13224==    by 0x80493B4: reset_configs (phpwrapperd.c:203)
==13224==    by 0x804A047: main (phpwrapperd.c:537)
==13224==  
==13224==  
==13224== 48 bytes in 2 blocks are still reachable in loss record 8 of 19
==13224==    at 0x1B90354C: malloc (vg_replace_malloc.c:130)
==13224==    by 0x8049825: get_user (phpwrapperd.c:315)
==13224==    by 0x8049B77: send_phpconfig (phpwrapperd.c:379)
==13224==    by 0x804A08D: main (phpwrapperd.c:555)
==13224==  
==13224==  
==13224== 60 bytes in 2 blocks are still reachable in loss record 9 of 19
==13224==    at 0x1B90354C: malloc (vg_replace_malloc.c:130)
==13224==    by 0x8049A5C: get_user (phpwrapperd.c:351)
==13224==    by 0x8049B77: send_phpconfig (phpwrapperd.c:379)
==13224==    by 0x804A08D: main (phpwrapperd.c:555)
==13224==  
==13224==  
==13224== 68 bytes in 1 blocks are possibly lost in loss record 10 of 19
==13224==    at 0x1B903E89: calloc (vg_replace_malloc.c:175)
==13224==    by 0x1B8F2C2B: _dl_allocate_tls (in /lib/ld-2.3.2.so)
==13224==    by 0x1B9E126D: allocate_stack (in /lib/tls/libpthread-0.60.so)
==13224==    by 0x1B9E0EF7: pthread_create@@GLIBC_2.1 (in /lib/tls/libpthread-0.60.so)
==13224==    by 0x8049EB8: main (phpwrapperd.c:499)
==13224==  
==13224==  
==13224== 96 bytes in 14 blocks are still reachable in loss record 11 of 19
==13224==    at 0x1B90354C: malloc (vg_replace_malloc.c:130)
==13224==    by 0x804A213: init_config (config.c:51)
==13224==    by 0x8049E3D: main (phpwrapperd.c:462)
==13224==  
==13224==  
==13224== 168 bytes in 14 blocks are still reachable in loss record 12 of 19
==13224==    at 0x1B90354C: malloc (vg_replace_malloc.c:130)
==13224==    by 0x804A1C3: init_config (config.c:49)
==13224==    by 0x8049E3D: main (phpwrapperd.c:462)
==13224==  
==13224==  
==13224== 187 bytes in 8 blocks are still reachable in loss record 13 of 19
==13224==    at 0x1B90354C: malloc (vg_replace_malloc.c:130)
==13224==    by 0x804913F: add (phpwrapperd.c:154)
==13224==    by 0x80493B4: reset_configs (phpwrapperd.c:203)
==13224==    by 0x804A047: main (phpwrapperd.c:537)
==13224==  
==13224==  
==13224== 192 bytes in 14 blocks are still reachable in loss record 14 of 19
==13224==    at 0x1B90354C: malloc (vg_replace_malloc.c:130)
==13224==    by 0x804A1EA: init_config (config.c:50)
==13224==    by 0x8049E3D: main (phpwrapperd.c:462)
==13224==  
==13224==  
==13224== 608 bytes in 76 blocks are indirectly lost in loss record 15 of 19
==13224==    at 0x1B903F72: realloc (vg_replace_malloc.c:196)
==13224==    by 0x80490E5: add (phpwrapperd.c:151)
==13224==    by 0x80493B4: reset_configs (phpwrapperd.c:203)
==13224==    by 0x804A047: main (phpwrapperd.c:537)
==13224==  
==13224==  
==13224== 760 bytes in 76 blocks are indirectly lost in loss record 16 of 19
==13224==    at 0x1B90354C: malloc (vg_replace_malloc.c:130)
==13224==    by 0x8049077: add (phpwrapperd.c:142)
==13224==    by 0x80493B4: reset_configs (phpwrapperd.c:203)
==13224==    by 0x804A047: main (phpwrapperd.c:537)
==13224==  
==13224==  
==13224== 3420 bytes in 152 blocks are indirectly lost in loss record 17 of 19
==13224==    at 0x1B90354C: malloc (vg_replace_malloc.c:130)
==13224==    by 0x804913F: add (phpwrapperd.c:154)
==13224==    by 0x80493B4: reset_configs (phpwrapperd.c:203)
==13224==    by 0x804A047: main (phpwrapperd.c:537)
==13224==  
==13224==  
==13224== 6004 (1216 direct, 4788 indirect) bytes in 76 blocks are definitely lost in loss record 18 of 19
==13224==    at 0x1B90354C: malloc (vg_replace_malloc.c:130)
==13224==    by 0x8048FFE: add (phpwrapperd.c:131)
==13224==    by 0x80493B4: reset_configs (phpwrapperd.c:203)
==13224==    by 0x804A047: main (phpwrapperd.c:537)
==13224==  
==13224==  
==13224== 24528 bytes in 6 blocks are still reachable in loss record 19 of 19
==13224==    at 0x1B90354C: malloc (vg_replace_malloc.c:130)
==13224==    by 0x1B923EA2: my_once_alloc (in /usr/lib/mysql/libmysqlclient.so.14.0.0)
==13224==    by 0x1B925244: init_state_maps (in /usr/lib/mysql/libmysqlclient.so.14.0.0)
==13224==    by 0x1B92510C: get_charset_by_csname (in /usr/lib/mysql/libmysqlclient.so.14.0.0)
==13224==    by 0x1B93564E: mysql_real_connect (in /usr/lib/mysql/libmysqlclient.so.14.0.0)
==13224==    by 0x8049262: reset_configs (phpwrapperd.c:172)
==13224==    by 0x804A047: main (phpwrapperd.c:537)
==13224==  
==13224== LEAK SUMMARY:
==13224==    definitely lost: 1216 bytes in 76 blocks.
==13224==    indirectly lost: 4788 bytes in 304 blocks.
==13224==      possibly lost: 68 bytes in 1 blocks.
==13224==    still reachable: 25393 bytes in 70 blocks.
==13224==         suppressed: 0 bytes in 0 blocks.


Il me dit bien qu'il y a des pertes de mémoire. Mais par où dois-je commencer pour résoudre ces erreurs ?
Merci
 :hello:

Reply

Marsh Posté le 21-04-2005 à 17:29:50   

Reply

Marsh Posté le 21-04-2005 à 19:21:19    


Sans le code, on peut pas t'aider.
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 21-04-2005 à 19:35:45    

oué, mais bon il t'indique les fonctions causant des fuites et le lieu de l'allocation, avec ca tu devrais y arriver


---------------
NP: HTTP Error 764 Stupid coder found
Reply

Marsh Posté le 22-04-2005 à 09:40:46    

Puisque c'est si gentillement demandé :)
Voici les parties du code qui pourraient poser problème :
 

Code :
  1. typedef struct _configs {
  2.   char* nom;
  3.   int n;
  4.   char** params;
  5.   struct _configs* next;
  6. } configs;
  7. typedef struct _users {
  8.   char* nom;
  9.   char* type;
  10.   char* open_basedir;
  11.   struct _users* last;
  12.   struct _users* next;
  13.   time_t timestamp;
  14. } users;
  15. configs* c;
  16. users* user;
  17. int n_users;
  18. void add(char* type, char* name, char* value) {
  19.   configs* d=c;
  20.   configs* e=NULL;
  21.   while (d!=NULL) {
  22.     if(d->nom==NULL || type==NULL)
  23.       return;
  24.     if(strcmp(d->nom,type)==0)
  25.       break;
  26.     e=d;
  27.     d=d->next;
  28.   }
  29.   if(d==NULL) {
  30.     if(e!=NULL) {
  31.       e->next=(configs*)malloc(sizeof(configs)); // Ligne 131
  32.       if(e->next==NULL)
  33. syslog(LOG_NOTICE,"Erreur d'allocation (121)" );
  34.       d=e->next;
  35.     }
  36.     else {
  37.       c=(configs*)malloc(sizeof(configs)); // Ligne 137
  38.       if(c==NULL)
  39. syslog(LOG_NOTICE,"Erreur d'allocation (127)" );
  40.       d=c;
  41.     }
  42.     d->nom=(char*)malloc((strlen(type)+1)*sizeof(char));
  43.     if(d->nom==NULL)
  44.       syslog(LOG_NOTICE,"Erreur d'allocation (132)" );
  45.     strcpy(d->nom,type);
  46.     d->n=0;
  47.     d->params=NULL;
  48.   }
  49.   d->n+=1;
  50.   d->params=(char**)realloc(d->params,d->n*sizeof(char*)); // Ligne 151
  51.   if(d->params==NULL)
  52.     syslog(LOG_NOTICE,"Erreur d'allocation (141)" );
  53.   d->params[d->n-1]=(char*)malloc((strlen(name)+strlen(value)+3)*sizeof(char));
  54.   if(d->params[d->n-1]==NULL)
  55.     syslog(LOG_NOTICE,"Erreur d'allocation (144)" );
  56.   d->next=NULL;
  57.   sprintf(d->params[d->n-1],"%s=%s\n",name,value);
  58. }
  59. void freeconfigs() {
  60.   int i;
  61.   configs *n,*d=c;
  62.   while(d!=NULL) {
  63.     n=d->next;
  64.     free(d->nom);
  65.     for(i=0;i<d->n;i++) {
  66.       free(d->params[i]);
  67.     }
  68.     if(d->params!=NULL) {
  69.       free(d->params);
  70.     }
  71.     free(d);
  72.     d=n;
  73.   }
  74.   c=NULL;
  75. }
  76. void reset_configs() {
  77.   MYSQL m;
  78.   int i, err;
  79.   MYSQL_RES *r1;
  80.   MYSQL_ROW row;
  81.   mysql_init(&m);
  82.   mysql_options(&m,MYSQL_READ_DEFAULT_GROUP,"phpwrapperd" );
  83.   for(i=0;i<getValueI("MYSQL_RETRY" );i++) {
  84.     if(!mysql_real_connect(&m,
  85.      getValueS("MYSQL_HOST" ),
  86.      getValueS("MYSQL_LOGIN" ),
  87.      getValueS("MYSQL_PASSWORD" ),
  88.      getValueS("MYSQL_DB" ),
  89.      0,
  90.      getValueS("MYSQL_SOCK" ),
  91.      0)) {
  92.       syslog(LOG_NOTICE, "Impossible de se connecter au server mysql : %s\n",mysql_error(&m));
  93.       if(i==getValueI("MYSQL_RETRY" )-1) {
  94. syslog(LOG_NOTICE,"!!! Abandon de connexion au serveur MySQL !!!" );
  95. return;
  96.       }
  97.     }
  98.     else
  99.       i=getValueI("MYSQL_RETRY" );
  100.   }
  101.  
  102.   mysql_query(&m,"select * from php_config" );
  103.   r1=mysql_store_result(&m);
  104.   if(r1==NULL) {
  105.     syslog(LOG_NOTICE,"`select * from php_config' : %s\n",mysql_error(&m));
  106.     mysql_close(&m);
  107.     return;
  108.   }
  109.   freeconfigs();
  110.   while ((row = mysql_fetch_row(r1))) {
  111.     mysql_commit(&m);
  112.     add(row[0],row[1],row[2]); // Ligne 203
  113.   }
  114.   mysql_free_result(r1);
  115.   mysql_close(&m);
  116. }
  117. void get_user(char* name, char** base_dir, char** type) {
  118.   MYSQL m;
  119.   int i, err;
  120.   char* query;
  121.   MYSQL_RES *r1;
  122.   MYSQL_ROW row;
  123.   users* u;
  124.   users* tmp;
  125.   int exists=1;
  126.   u=user;
  127.   if(user==NULL)
  128.     exists=0;
  129.   else {
  130.     if(user->nom==NULL || name==NULL)
  131.       return;
  132.     while(strcmp(u->nom,name)) {
  133.       u=u->next;
  134.       if(u==user) {
  135. exists=0;
  136. break;
  137.       }
  138.     }
  139.   }
  140.   if(!exists || u->timestamp<(time(NULL)-getValueI("REFRESH_CACHE_USERS_DELAY" ))) {
  141.     query=(char*)malloc((49+strlen(name))*sizeof(char));
  142.     if(query==NULL)
  143.       syslog(LOG_NOTICE,"Erreur d'allocation (272)" );
  144.     sprintf(query,"select type,homedir from users where username='%s'",name);
  145.    
  146.     mysql_init(&m);
  147.     mysql_options(&m,MYSQL_READ_DEFAULT_GROUP,"phpwrapperd" );
  148.    
  149.     for(i=0;i<getValueI("MYSQL_RETRY" );i++) {
  150.       if(!mysql_real_connect(&m,
  151.        getValueS("MYSQL_HOST" ),
  152.        getValueS("MYSQL_LOGIN" ),
  153.        getValueS("MYSQL_PASSWORD" ),
  154.        getValueS("MYSQL_DB" ),
  155.        0,
  156.        getValueS("MYSQL_SOCK" ),
  157.        0)) {
  158. syslog(LOG_NOTICE,"Impossible de se connecter au server mysql : %s\n",mysql_error(&m));
  159. if(i==getValueI("MYSQL_RETRY" )-1) {
  160.   syslog(LOG_NOTICE,"!!! Abandon de connexion au serveur MySQL !!!" );
  161.   free(query);
  162.   return;
  163. }
  164.       }
  165.       else
  166. break;
  167.     }
  168.    
  169.     mysql_query(&m,query);
  170.     r1=mysql_store_result(&m);
  171.     if(mysql_num_rows(r1)==0 || r1==NULL){
  172.       if(r1==NULL)
  173. syslog(LOG_NOTICE,"`%s' : %s\n",query, mysql_error(&m));
  174.       *base_dir=NULL;
  175.       *type=NULL;
  176.       mysql_free_result(r1);
  177.       mysql_close(&m);
  178.       free(query);
  179.       return;
  180.     }
  181.     if(!exists)
  182.       syslog(LOG_NOTICE,"Adding user `%s' in cache", name); 
  183.     else
  184.       syslog(LOG_NOTICE,"Updating user `%s' in cache", name); 
  185.    
  186.     if(n_users>=getValueI("MAX_USERS_CACHE" ))
  187.       free_last_user();
  188.    
  189.     u=(users*)malloc(sizeof(users));
  190.     if(u==NULL)
  191.       syslog(LOG_NOTICE,"Erreur d'allocation (302)" );
  192.     if(user==NULL) {
  193.       u->last=u;
  194.       u->next=u;
  195.       n_users=1;
  196.     }
  197.     else {
  198.       tmp=user->last;
  199.       u->last=tmp;
  200.       u->next=user;
  201.       user->last=u;
  202.       u->last->next=u;
  203.       n_users++;
  204.     }
  205.     u->nom=NULL;
  206.     u->type=NULL;
  207.     u->open_basedir=NULL;
  208.     user=u;
  209.     if(u->nom!=NULL) free(u->nom);
  210.     u->nom=(char*)malloc((strlen(name)+1)*sizeof(char)); // Ligne 338
  211.     if(u->nom==NULL)
  212.       syslog(LOG_NOTICE,"Erreur d'allocation (344)" );
  213.     strcpy(u->nom,name);
  214.    
  215.     row = mysql_fetch_row(r1);
  216.     mysql_commit(&m);
  217.     if(u->type!=NULL) free(u->type);
  218.     u->type=(char*)malloc((strlen(row[0])+1)*sizeof(char));  // Ligne 346
  219.     if(u->type==NULL)
  220.       syslog(LOG_NOTICE,"Erreur d'allocation (352)" );
  221.     strcpy(u->type,row[0]);
  222.     if(u->open_basedir!=NULL) free(u->open_basedir);
  223.     u->open_basedir=(char*)malloc((strlen(row[1])+1)*sizeof(char));
  224.     if(u->open_basedir==NULL)
  225.       syslog(LOG_NOTICE,"Erreur d'allocation (357)" );
  226.     strcpy(u->open_basedir,row[1]);
  227.     mysql_free_result(r1);
  228.     mysql_close(&m);
  229.     free(query);
  230.    
  231.     u->timestamp=time(NULL);
  232.     exists=1;
  233.   }
  234.   else {
  235.     *base_dir=u->open_basedir;
  236.     *type=u->type;
  237.   }
  238. }
  239. void send_phpconfig() {
  240.   configs* d=c;
  241.   char line[MAXLINE];
  242.   char *openbase_dir=NULL;
  243.   char *type=NULL;
  244.   int i;
  245.   readline(newsockfd,line,MAXLINE);
  246.   get_user(line,&openbase_dir,&type); // Ligne 379
  247.   if (openbase_dir==NULL || type==NULL) {
  248.     syslog(LOG_NOTICE,"unknown user `%s'",line);
  249.     return;
  250.   }
  251.   d=c;
  252.   if(d!=NULL) {
  253.     if(d->nom==NULL || type==NULL)
  254.       return;
  255.     while(strcmp(d->nom,type))
  256.       d=d->next;
  257.     for(i=0;i<d->n;i++){
  258.       writen(newsockfd,d->params[i],strlen(d->params[i]));
  259.     }
  260.   }
  261.   sprintf(line,"open_basedir=%s\n",openbase_dir);
  262.   writen(newsockfd,line,strlen(line)+1);
  263.   writen(newsockfd,"\n",1);
  264. }


 
EDIT : ajout des n° de ligne utiles


Message édité par Profil supprimé le 22-04-2005 à 09:51:27
Reply

Marsh Posté le 22-04-2005 à 10:58:58    

ha! sauf que tes numéros de lignes ne correspondent pas aux numéros de lignes de valgrind...
Par exemple:
==13224== 4 bytes in 1 blocks are still reachable in loss record 1 of 19
==13224==    at 0x1B90354C: malloc (vg_replace_malloc.c:130)
==13224==    by 0x1B903EFB: realloc vg_replace_malloc.c:188)
==13224==    by 0x80490E5: add (phpwrapperd.c:151)
==13224==    by 0x80493B4: reset_configs (phpwrapperd.c:203)
==13224==    by 0x804A047: main (phpwrapperd.c:537)
==
 
C'est-à-dire que tu fais un alloc sans free à la ligne 151 du fichier phpwrapperd.c, dans la fonction add

Reply

Marsh Posté le 22-04-2005 à 11:44:05    

J'ai mis les n° de lignes en commentaires aux endroits indiqués par valgrind ;)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed